Skip to content

Commit 6e2faac

Browse files
Harden transport error payload stringification
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 8894ddf commit 6e2faac

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

hyperbrowser/transport/error_utils.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@
4545
}
4646

4747

48+
def _safe_to_string(value: Any) -> str:
49+
try:
50+
return str(value)
51+
except Exception:
52+
return f"<unstringifiable {type(value).__name__}>"
53+
54+
4855
def _normalize_request_method(method: Any) -> str:
4956
raw_method = method
5057
if isinstance(raw_method, bool):
@@ -121,7 +128,7 @@ def _truncate_error_message(message: str) -> str:
121128

122129
def _stringify_error_value(value: Any, *, _depth: int = 0) -> str:
123130
if _depth > 10:
124-
return str(value)
131+
return _safe_to_string(value)
125132
if isinstance(value, str):
126133
return value
127134
if isinstance(value, dict):
@@ -152,7 +159,7 @@ def _stringify_error_value(value: Any, *, _depth: int = 0) -> str:
152159
try:
153160
return json.dumps(value, sort_keys=True)
154161
except (TypeError, ValueError, RecursionError):
155-
return str(value)
162+
return _safe_to_string(value)
156163

157164

158165
def extract_error_message(response: httpx.Response, fallback_error: Exception) -> str:

tests/test_transport_error_utils.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ def json(self):
143143
return self._json_value
144144

145145

146+
class _UnstringifiableErrorValue:
147+
def __str__(self) -> str:
148+
raise RuntimeError("cannot stringify error value")
149+
150+
146151
def test_extract_request_error_context_uses_unknown_when_request_unset():
147152
method, url = extract_request_error_context(httpx.RequestError("network down"))
148153

@@ -631,6 +636,15 @@ def test_extract_error_message_handles_recursive_dict_payloads():
631636
assert message
632637

633638

639+
def test_extract_error_message_handles_unstringifiable_message_values():
640+
message = extract_error_message(
641+
_DummyResponse({"message": _UnstringifiableErrorValue()}),
642+
RuntimeError("fallback detail"),
643+
)
644+
645+
assert message == "<unstringifiable _UnstringifiableErrorValue>"
646+
647+
634648
def test_extract_error_message_uses_fallback_for_blank_dict_message():
635649
message = extract_error_message(
636650
_DummyResponse({"message": " "}), RuntimeError("fallback detail")

0 commit comments

Comments
 (0)