Skip to content

Commit 6962067

Browse files
Treat HTTP 408 as retryable in polling helpers
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent d15fe43 commit 6962067

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

hyperbrowser/client/polling.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
_MAX_OPERATION_NAME_LENGTH = 200
1616
_CLIENT_ERROR_STATUS_MIN = 400
1717
_CLIENT_ERROR_STATUS_MAX = 500
18-
_RETRYABLE_CLIENT_ERROR_STATUS_CODES = {429}
18+
_RETRYABLE_CLIENT_ERROR_STATUS_CODES = {408, 429}
1919

2020

2121
class _NonRetryablePollingError(HyperbrowserError):

tests/test_polling.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,28 @@ def get_status() -> str:
182182
assert attempts["count"] == 3
183183

184184

185+
def test_poll_until_terminal_status_retries_request_timeout_errors():
186+
attempts = {"count": 0}
187+
188+
def get_status() -> str:
189+
attempts["count"] += 1
190+
if attempts["count"] < 3:
191+
raise HyperbrowserError("request timeout", status_code=408)
192+
return "completed"
193+
194+
status = poll_until_terminal_status(
195+
operation_name="sync poll request-timeout retries",
196+
get_status=get_status,
197+
is_terminal_status=lambda value: value == "completed",
198+
poll_interval_seconds=0.0001,
199+
max_wait_seconds=1.0,
200+
max_status_failures=5,
201+
)
202+
203+
assert status == "completed"
204+
assert attempts["count"] == 3
205+
206+
185207
def test_poll_until_terminal_status_async_retries_rate_limit_errors():
186208
async def run() -> None:
187209
attempts = {"count": 0}
@@ -207,6 +229,31 @@ async def get_status() -> str:
207229
asyncio.run(run())
208230

209231

232+
def test_poll_until_terminal_status_async_retries_request_timeout_errors():
233+
async def run() -> None:
234+
attempts = {"count": 0}
235+
236+
async def get_status() -> str:
237+
attempts["count"] += 1
238+
if attempts["count"] < 3:
239+
raise HyperbrowserError("request timeout", status_code=408)
240+
return "completed"
241+
242+
status = await poll_until_terminal_status_async(
243+
operation_name="async poll request-timeout retries",
244+
get_status=get_status,
245+
is_terminal_status=lambda value: value == "completed",
246+
poll_interval_seconds=0.0001,
247+
max_wait_seconds=1.0,
248+
max_status_failures=5,
249+
)
250+
251+
assert status == "completed"
252+
assert attempts["count"] == 3
253+
254+
asyncio.run(run())
255+
256+
210257
def test_poll_until_terminal_status_async_handles_non_integer_status_codes_as_retryable():
211258
async def run() -> None:
212259
attempts = {"count": 0}
@@ -437,6 +484,26 @@ def operation() -> str:
437484
assert attempts["count"] == 3
438485

439486

487+
def test_retry_operation_retries_request_timeout_errors():
488+
attempts = {"count": 0}
489+
490+
def operation() -> str:
491+
attempts["count"] += 1
492+
if attempts["count"] < 3:
493+
raise HyperbrowserError("request timeout", status_code=408)
494+
return "ok"
495+
496+
result = retry_operation(
497+
operation_name="sync retry request-timeout error",
498+
operation=operation,
499+
max_attempts=5,
500+
retry_delay_seconds=0.0001,
501+
)
502+
503+
assert result == "ok"
504+
assert attempts["count"] == 3
505+
506+
440507
def test_retry_operation_handles_non_integer_status_codes_as_retryable():
441508
attempts = {"count": 0}
442509

@@ -748,6 +815,29 @@ async def operation() -> str:
748815
asyncio.run(run())
749816

750817

818+
def test_retry_operation_async_retries_request_timeout_errors():
819+
async def run() -> None:
820+
attempts = {"count": 0}
821+
822+
async def operation() -> str:
823+
attempts["count"] += 1
824+
if attempts["count"] < 3:
825+
raise HyperbrowserError("request timeout", status_code=408)
826+
return "ok"
827+
828+
result = await retry_operation_async(
829+
operation_name="async retry request-timeout error",
830+
operation=operation,
831+
max_attempts=5,
832+
retry_delay_seconds=0.0001,
833+
)
834+
835+
assert result == "ok"
836+
assert attempts["count"] == 3
837+
838+
asyncio.run(run())
839+
840+
751841
def test_async_poll_until_terminal_status_allows_immediate_terminal_on_zero_max_wait():
752842
async def run() -> None:
753843
status = await poll_until_terminal_status_async(

0 commit comments

Comments
 (0)