Skip to content

Commit 8894ddf

Browse files
Wrap unreadable APIResponse mapping keys
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent da80e9e commit 8894ddf

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

hyperbrowser/transport/base.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,17 @@ def from_json(
2828
f"Failed to parse response data for {model_name}: "
2929
f"expected a mapping but received {actual_type_name}"
3030
)
31-
for key in json_data.keys():
31+
try:
32+
response_keys = list(json_data.keys())
33+
except HyperbrowserError:
34+
raise
35+
except Exception as exc:
36+
raise HyperbrowserError(
37+
f"Failed to parse response data for {model_name}: "
38+
"unable to read mapping keys",
39+
original_error=exc,
40+
) from exc
41+
for key in response_keys:
3242
if isinstance(key, str):
3343
continue
3444
key_type_name = type(key).__name__

tests/test_transport_base.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections.abc import Mapping
12
from typing import cast
23

34
import pytest
@@ -18,6 +19,18 @@ def __init__(self, **kwargs):
1819
raise HyperbrowserError("model validation failed")
1920

2021

22+
class _BrokenKeysMapping(Mapping[str, object]):
23+
def __iter__(self):
24+
raise RuntimeError("cannot iterate mapping keys")
25+
26+
def __len__(self) -> int:
27+
return 1
28+
29+
def __getitem__(self, key: str) -> object:
30+
_ = key
31+
return "value"
32+
33+
2134
def test_api_response_from_json_parses_model_data() -> None:
2235
response = APIResponse.from_json(
2336
{"name": "job-1", "retries": 2}, _SampleResponseModel
@@ -67,6 +80,19 @@ def test_api_response_from_json_wraps_non_hyperbrowser_errors() -> None:
6780
assert exc_info.value.original_error is not None
6881

6982

83+
def test_api_response_from_json_wraps_unreadable_mapping_keys() -> None:
84+
with pytest.raises(
85+
HyperbrowserError,
86+
match=(
87+
"Failed to parse response data for _SampleResponseModel: "
88+
"unable to read mapping keys"
89+
),
90+
) as exc_info:
91+
APIResponse.from_json(_BrokenKeysMapping(), _SampleResponseModel)
92+
93+
assert exc_info.value.original_error is not None
94+
95+
7096
def test_api_response_from_json_preserves_hyperbrowser_errors() -> None:
7197
with pytest.raises(HyperbrowserError, match="model validation failed") as exc_info:
7298
APIResponse.from_json({}, _RaisesHyperbrowserModel)

0 commit comments

Comments
 (0)