Skip to content

Commit 59c214a

Browse files
Normalize bytes-like URL fallbacks in transport errors
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 17f1725 commit 59c214a

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ Polling timeouts and repeated polling failures are surfaced as:
187187

188188
`HyperbrowserPollingError` also covers stalled pagination (no page-batch progress during result collection).
189189
Transport-level request failures include HTTP method + URL context in error messages.
190-
URL-like fallback objects are stringified for transport diagnostics; missing/malformed/sentinel URL inputs (for example `None`, booleans, `null`/`undefined`/`nan`, or numeric-like values such as `123`/`1.5`/`1e6`) are normalized to `unknown URL`.
190+
URL-like fallback objects are stringified for transport diagnostics, and bytes-like fallback URL values are UTF-8 decoded when valid; missing/malformed/sentinel URL inputs (for example `None`, booleans, invalid bytes, `null`/`undefined`/`nan`, or numeric-like values such as `123`/`1.5`/`1e6`) are normalized to `unknown URL`.
191191

192192
```python
193193
from hyperbrowser import Hyperbrowser

hyperbrowser/transport/error_utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ def _normalize_request_url(url: Any) -> str:
4242
if isinstance(url, bool):
4343
return "unknown URL"
4444
raw_url = url
45-
if not isinstance(raw_url, str):
45+
if isinstance(raw_url, (bytes, bytearray, memoryview)):
46+
try:
47+
raw_url = memoryview(raw_url).tobytes().decode("utf-8")
48+
except (TypeError, ValueError, UnicodeDecodeError):
49+
return "unknown URL"
50+
elif not isinstance(raw_url, str):
4651
try:
4752
raw_url = str(raw_url)
4853
except Exception:

tests/test_transport_error_utils.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,26 @@ def test_format_request_failure_message_supports_url_like_fallback_values():
316316
assert message == "Request GET https://example.com/fallback failed"
317317

318318

319+
def test_format_request_failure_message_supports_utf8_bytes_fallback_values():
320+
message = format_request_failure_message(
321+
httpx.RequestError("network down"),
322+
fallback_method="GET",
323+
fallback_url=b"https://example.com/bytes",
324+
)
325+
326+
assert message == "Request GET https://example.com/bytes failed"
327+
328+
329+
def test_format_request_failure_message_normalizes_invalid_bytes_fallback_values():
330+
message = format_request_failure_message(
331+
httpx.RequestError("network down"),
332+
fallback_method="GET",
333+
fallback_url=b"\xff\xfe\xfd",
334+
)
335+
336+
assert message == "Request GET unknown URL failed"
337+
338+
319339
def test_format_generic_request_failure_message_normalizes_invalid_url_objects():
320340
message = format_generic_request_failure_message(
321341
method="GET",
@@ -390,6 +410,15 @@ def test_format_generic_request_failure_message_supports_url_like_values():
390410
assert message == "Request GET https://example.com/path failed"
391411

392412

413+
def test_format_generic_request_failure_message_supports_utf8_memoryview_urls():
414+
message = format_generic_request_failure_message(
415+
method="GET",
416+
url=memoryview(b"https://example.com/memoryview"),
417+
)
418+
419+
assert message == "Request GET https://example.com/memoryview failed"
420+
421+
393422
def test_format_generic_request_failure_message_normalizes_invalid_method_values():
394423
message = format_generic_request_failure_message(
395424
method="GET /invalid",

0 commit comments

Comments
 (0)