Skip to content

Commit 647f1d6

Browse files
Normalize numeric URL-like fallbacks to unknown URL in transport errors
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 6b3e84e commit 647f1d6

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

hyperbrowser/transport/error_utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ def _normalize_request_url(url: Any) -> str:
3434
normalized_url = raw_url.strip()
3535
if not normalized_url:
3636
return "unknown URL"
37+
lowered_url = normalized_url.lower()
38+
if lowered_url in {"none", "null"} or normalized_url.isdigit():
39+
return "unknown URL"
3740
if any(character.isspace() for character in normalized_url):
3841
return "unknown URL"
3942
if any(

tests/test_transport_error_utils.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,16 @@ def test_format_request_failure_message_normalizes_non_string_fallback_values():
245245
assert message == "Request UNKNOWN unknown URL failed"
246246

247247

248+
def test_format_request_failure_message_normalizes_numeric_fallback_url_values():
249+
message = format_request_failure_message(
250+
httpx.RequestError("network down"),
251+
fallback_method="GET",
252+
fallback_url=123,
253+
)
254+
255+
assert message == "Request GET unknown URL failed"
256+
257+
248258
def test_format_request_failure_message_supports_url_like_fallback_values():
249259
message = format_request_failure_message(
250260
httpx.RequestError("network down"),
@@ -264,6 +274,15 @@ def test_format_generic_request_failure_message_normalizes_invalid_url_objects()
264274
assert message == "Request GET unknown URL failed"
265275

266276

277+
def test_format_generic_request_failure_message_normalizes_numeric_url_values():
278+
message = format_generic_request_failure_message(
279+
method="GET",
280+
url=123,
281+
)
282+
283+
assert message == "Request GET unknown URL failed"
284+
285+
267286
def test_format_generic_request_failure_message_supports_url_like_values():
268287
message = format_generic_request_failure_message(
269288
method="GET",

tests/test_transport_response_handling.py

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

380380

381+
def test_sync_transport_wraps_unexpected_errors_with_numeric_url_fallback():
382+
transport = SyncTransport(api_key="test-key")
383+
original_get = transport.client.get
384+
385+
def failing_get(*args, **kwargs):
386+
raise RuntimeError("boom")
387+
388+
transport.client.get = failing_get # type: ignore[assignment]
389+
try:
390+
with pytest.raises(HyperbrowserError, match="Request GET unknown URL failed"):
391+
transport.get(123) # type: ignore[arg-type]
392+
finally:
393+
transport.client.get = original_get # type: ignore[assignment]
394+
transport.close()
395+
396+
381397
def test_async_transport_put_wraps_unexpected_errors_with_url_context():
382398
async def run() -> None:
383399
transport = AsyncTransport(api_key="test-key")
@@ -421,6 +437,27 @@ async def failing_put(*args, **kwargs):
421437
asyncio.run(run())
422438

423439

440+
def test_async_transport_wraps_unexpected_errors_with_numeric_url_fallback():
441+
async def run() -> None:
442+
transport = AsyncTransport(api_key="test-key")
443+
original_put = transport.client.put
444+
445+
async def failing_put(*args, **kwargs):
446+
raise RuntimeError("boom")
447+
448+
transport.client.put = failing_put # type: ignore[assignment]
449+
try:
450+
with pytest.raises(
451+
HyperbrowserError, match="Request PUT unknown URL failed"
452+
):
453+
await transport.put(123) # type: ignore[arg-type]
454+
finally:
455+
transport.client.put = original_put # type: ignore[assignment]
456+
await transport.close()
457+
458+
asyncio.run(run())
459+
460+
424461
def test_sync_transport_request_error_without_request_uses_fallback_url():
425462
transport = SyncTransport(api_key="test-key")
426463
original_get = transport.client.get
@@ -473,6 +510,22 @@ def failing_get(*args, **kwargs):
473510
transport.close()
474511

475512

513+
def test_sync_transport_request_error_without_request_uses_unknown_url_for_numeric_input():
514+
transport = SyncTransport(api_key="test-key")
515+
original_get = transport.client.get
516+
517+
def failing_get(*args, **kwargs):
518+
raise httpx.RequestError("network down")
519+
520+
transport.client.get = failing_get # type: ignore[assignment]
521+
try:
522+
with pytest.raises(HyperbrowserError, match="Request GET unknown URL failed"):
523+
transport.get(123) # type: ignore[arg-type]
524+
finally:
525+
transport.client.get = original_get # type: ignore[assignment]
526+
transport.close()
527+
528+
476529
def test_async_transport_request_error_without_request_uses_fallback_url():
477530
async def run() -> None:
478531
transport = AsyncTransport(api_key="test-key")
@@ -536,3 +589,24 @@ async def failing_delete(*args, **kwargs):
536589
await transport.close()
537590

538591
asyncio.run(run())
592+
593+
594+
def test_async_transport_request_error_without_request_uses_unknown_url_for_numeric_input():
595+
async def run() -> None:
596+
transport = AsyncTransport(api_key="test-key")
597+
original_delete = transport.client.delete
598+
599+
async def failing_delete(*args, **kwargs):
600+
raise httpx.RequestError("network down")
601+
602+
transport.client.delete = failing_delete # type: ignore[assignment]
603+
try:
604+
with pytest.raises(
605+
HyperbrowserError, match="Request DELETE unknown URL failed"
606+
):
607+
await transport.delete(123) # type: ignore[arg-type]
608+
finally:
609+
transport.client.delete = original_delete # type: ignore[assignment]
610+
await transport.close()
611+
612+
asyncio.run(run())

0 commit comments

Comments
 (0)