Skip to content

Commit cf8f959

Browse files
Wrap tool param-key empty-check length failures
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 34a498a commit cf8f959

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

hyperbrowser/tools/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,15 @@ def _to_param_dict(params: Mapping[str, Any]) -> Dict[str, Any]:
146146
normalized_key = key.strip()
147147
if not isinstance(normalized_key, str):
148148
raise TypeError("normalized tool param key must be a string")
149+
is_empty_key = len(normalized_key) == 0
149150
except HyperbrowserError:
150151
raise
151152
except Exception as exc:
152153
raise HyperbrowserError(
153154
"Failed to normalize tool param key",
154155
original_error=exc,
155156
) from exc
156-
if not normalized_key:
157+
if is_empty_key:
157158
raise HyperbrowserError("tool params keys must not be empty")
158159
try:
159160
has_surrounding_whitespace = key != normalized_key

tests/test_tools_mapping_inputs.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,46 @@ def strip(self, chars=None): # type: ignore[override]
300300
assert isinstance(exc_info.value.original_error, TypeError)
301301

302302

303+
@pytest.mark.parametrize("runner", [_run_scrape_tool_sync, _run_scrape_tool_async])
304+
def test_tool_wrappers_wrap_param_key_empty_check_length_failures(runner):
305+
class _BrokenStripKey(str):
306+
class _NormalizedKey(str):
307+
def __len__(self):
308+
raise RuntimeError("tool param key length exploded")
309+
310+
def strip(self, chars=None): # type: ignore[override]
311+
_ = chars
312+
return self._NormalizedKey("url")
313+
314+
with pytest.raises(
315+
HyperbrowserError, match="Failed to normalize tool param key"
316+
) as exc_info:
317+
runner({_BrokenStripKey("url"): "https://example.com"})
318+
319+
assert isinstance(exc_info.value.original_error, RuntimeError)
320+
321+
322+
@pytest.mark.parametrize("runner", [_run_scrape_tool_sync, _run_scrape_tool_async])
323+
def test_tool_wrappers_preserve_hyperbrowser_param_key_empty_check_length_failures(
324+
runner,
325+
):
326+
class _BrokenStripKey(str):
327+
class _NormalizedKey(str):
328+
def __len__(self):
329+
raise HyperbrowserError("custom tool param key length failure")
330+
331+
def strip(self, chars=None): # type: ignore[override]
332+
_ = chars
333+
return self._NormalizedKey("url")
334+
335+
with pytest.raises(
336+
HyperbrowserError, match="custom tool param key length failure"
337+
) as exc_info:
338+
runner({_BrokenStripKey("url"): "https://example.com"})
339+
340+
assert exc_info.value.original_error is None
341+
342+
303343
@pytest.mark.parametrize("runner", [_run_scrape_tool_sync, _run_scrape_tool_async])
304344
def test_tool_wrappers_wrap_param_key_character_validation_failures(runner):
305345
class _BrokenIterKey(str):

0 commit comments

Comments
 (0)