Skip to content

Commit 8d22109

Browse files
Wrap finite-check failures with original error context
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent dd836d2 commit 8d22109

4 files changed

Lines changed: 65 additions & 4 deletions

File tree

hyperbrowser/client/polling.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,11 @@ def _normalize_non_negative_real(value: float, *, field_name: str) -> float:
8989
) from exc
9090
try:
9191
is_finite = math.isfinite(normalized_value)
92-
except (TypeError, ValueError, OverflowError):
93-
is_finite = False
92+
except (TypeError, ValueError, OverflowError) as exc:
93+
raise HyperbrowserError(
94+
f"{field_name} must be finite",
95+
original_error=exc,
96+
) from exc
9497
if not is_finite:
9598
raise HyperbrowserError(f"{field_name} must be finite")
9699
if normalized_value < 0:

hyperbrowser/client/timeout_utils.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ def validate_timeout_seconds(timeout: Optional[float]) -> Optional[float]:
2323
) from exc
2424
try:
2525
is_finite = math.isfinite(normalized_timeout)
26-
except (TypeError, ValueError, OverflowError):
27-
is_finite = False
26+
except (TypeError, ValueError, OverflowError) as exc:
27+
raise HyperbrowserError(
28+
"timeout must be finite",
29+
original_error=exc,
30+
) from exc
2831
if not is_finite:
2932
raise HyperbrowserError("timeout must be finite")
3033
if normalized_timeout < 0:

tests/test_client_timeout.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import pytest
77

8+
import hyperbrowser.client.timeout_utils as timeout_helpers
89
from hyperbrowser import AsyncHyperbrowser, Hyperbrowser
910
from hyperbrowser.exceptions import HyperbrowserError
1011

@@ -130,3 +131,33 @@ def test_async_client_rejects_overflowing_real_timeout():
130131
AsyncHyperbrowser(api_key="test-key", timeout=Fraction(10**1000, 1))
131132

132133
assert exc_info.value.original_error is not None
134+
135+
136+
def test_sync_client_wraps_timeout_isfinite_failures(
137+
monkeypatch: pytest.MonkeyPatch,
138+
):
139+
def _raise_isfinite_error(value: float) -> bool:
140+
_ = value
141+
raise OverflowError("finite check overflow")
142+
143+
monkeypatch.setattr(timeout_helpers.math, "isfinite", _raise_isfinite_error)
144+
145+
with pytest.raises(HyperbrowserError, match="timeout must be finite") as exc_info:
146+
Hyperbrowser(api_key="test-key", timeout=1)
147+
148+
assert exc_info.value.original_error is not None
149+
150+
151+
def test_async_client_wraps_timeout_isfinite_failures(
152+
monkeypatch: pytest.MonkeyPatch,
153+
):
154+
def _raise_isfinite_error(value: float) -> bool:
155+
_ = value
156+
raise OverflowError("finite check overflow")
157+
158+
monkeypatch.setattr(timeout_helpers.math, "isfinite", _raise_isfinite_error)
159+
160+
with pytest.raises(HyperbrowserError, match="timeout must be finite") as exc_info:
161+
AsyncHyperbrowser(api_key="test-key", timeout=1)
162+
163+
assert exc_info.value.original_error is not None

tests/test_polling.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,30 @@ def test_poll_until_terminal_status_returns_terminal_value():
4343
assert status == "completed"
4444

4545

46+
def test_poll_until_terminal_status_wraps_isfinite_failures(
47+
monkeypatch: pytest.MonkeyPatch,
48+
):
49+
def _raise_isfinite_error(value: float) -> bool:
50+
_ = value
51+
raise OverflowError("finite check overflow")
52+
53+
monkeypatch.setattr(polling_helpers.math, "isfinite", _raise_isfinite_error)
54+
55+
with pytest.raises(
56+
HyperbrowserError,
57+
match="poll_interval_seconds must be finite",
58+
) as exc_info:
59+
poll_until_terminal_status(
60+
operation_name="sync poll finite check",
61+
get_status=lambda: "completed",
62+
is_terminal_status=lambda value: value == "completed",
63+
poll_interval_seconds=0.1,
64+
max_wait_seconds=1.0,
65+
)
66+
67+
assert exc_info.value.original_error is not None
68+
69+
4670
def test_build_fetch_operation_name_prefixes_when_within_length_limit():
4771
assert build_fetch_operation_name("crawl job 123") == "Fetching crawl job 123"
4872

0 commit comments

Comments
 (0)