Skip to content

Commit da731d4

Browse files
Normalize true/false URL sentinels in transport diagnostics
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 80f5180 commit da731d4

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
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, bytes-like fallback methods/URLs are decoded when valid, and 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`.
190+
URL-like fallback objects are stringified for transport diagnostics, bytes-like fallback methods/URLs are decoded when valid, and missing/malformed/sentinel URL inputs (for example `None`, booleans, invalid bytes, `null`/`undefined`/`true`/`false`/`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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"none",
1616
"null",
1717
"undefined",
18+
"true",
19+
"false",
1820
"nan",
1921
"inf",
2022
"+inf",

tests/test_transport_error_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ def test_format_request_failure_message_normalizes_boolean_fallback_url_values()
332332
"none",
333333
"null",
334334
"undefined",
335+
"true",
336+
"false",
335337
"nan",
336338
"inf",
337339
"+inf",
@@ -429,6 +431,8 @@ def test_format_generic_request_failure_message_normalizes_boolean_url_values():
429431
"none",
430432
"null",
431433
"undefined",
434+
"true",
435+
"false",
432436
"nan",
433437
"inf",
434438
"+inf",

tests/test_transport_response_handling.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,22 @@ def failing_get(*args, **kwargs):
426426
transport.close()
427427

428428

429+
def test_sync_transport_wraps_unexpected_errors_with_boolean_string_url_fallback():
430+
transport = SyncTransport(api_key="test-key")
431+
original_get = transport.client.get
432+
433+
def failing_get(*args, **kwargs):
434+
raise RuntimeError("boom")
435+
436+
transport.client.get = failing_get # type: ignore[assignment]
437+
try:
438+
with pytest.raises(HyperbrowserError, match="Request GET unknown URL failed"):
439+
transport.get("true")
440+
finally:
441+
transport.client.get = original_get # type: ignore[assignment]
442+
transport.close()
443+
444+
429445
def test_sync_transport_wraps_unexpected_errors_with_numeric_like_string_url_fallback():
430446
transport = SyncTransport(api_key="test-key")
431447
original_get = transport.client.get
@@ -548,6 +564,27 @@ async def failing_put(*args, **kwargs):
548564
asyncio.run(run())
549565

550566

567+
def test_async_transport_wraps_unexpected_errors_with_boolean_string_url_fallback():
568+
async def run() -> None:
569+
transport = AsyncTransport(api_key="test-key")
570+
original_put = transport.client.put
571+
572+
async def failing_put(*args, **kwargs):
573+
raise RuntimeError("boom")
574+
575+
transport.client.put = failing_put # type: ignore[assignment]
576+
try:
577+
with pytest.raises(
578+
HyperbrowserError, match="Request PUT unknown URL failed"
579+
):
580+
await transport.put("false")
581+
finally:
582+
transport.client.put = original_put # type: ignore[assignment]
583+
await transport.close()
584+
585+
asyncio.run(run())
586+
587+
551588
def test_async_transport_wraps_unexpected_errors_with_numeric_like_string_url_fallback():
552589
async def run() -> None:
553590
transport = AsyncTransport(api_key="test-key")
@@ -669,6 +706,22 @@ def failing_get(*args, **kwargs):
669706
transport.close()
670707

671708

709+
def test_sync_transport_request_error_without_request_uses_unknown_url_for_boolean_string_input():
710+
transport = SyncTransport(api_key="test-key")
711+
original_get = transport.client.get
712+
713+
def failing_get(*args, **kwargs):
714+
raise httpx.RequestError("network down")
715+
716+
transport.client.get = failing_get # type: ignore[assignment]
717+
try:
718+
with pytest.raises(HyperbrowserError, match="Request GET unknown URL failed"):
719+
transport.get("true")
720+
finally:
721+
transport.client.get = original_get # type: ignore[assignment]
722+
transport.close()
723+
724+
672725
def test_sync_transport_request_error_without_request_uses_unknown_url_for_numeric_like_string_input():
673726
transport = SyncTransport(api_key="test-key")
674727
original_get = transport.client.get
@@ -813,6 +866,27 @@ async def failing_delete(*args, **kwargs):
813866
asyncio.run(run())
814867

815868

869+
def test_async_transport_request_error_without_request_uses_unknown_url_for_boolean_string_input():
870+
async def run() -> None:
871+
transport = AsyncTransport(api_key="test-key")
872+
original_delete = transport.client.delete
873+
874+
async def failing_delete(*args, **kwargs):
875+
raise httpx.RequestError("network down")
876+
877+
transport.client.delete = failing_delete # type: ignore[assignment]
878+
try:
879+
with pytest.raises(
880+
HyperbrowserError, match="Request DELETE unknown URL failed"
881+
):
882+
await transport.delete("false")
883+
finally:
884+
transport.client.delete = original_delete # type: ignore[assignment]
885+
await transport.close()
886+
887+
asyncio.run(run())
888+
889+
816890
def test_async_transport_request_error_without_request_uses_unknown_url_for_numeric_like_string_input():
817891
async def run() -> None:
818892
transport = AsyncTransport(api_key="test-key")

0 commit comments

Comments
 (0)