@@ -144,6 +144,31 @@ def get_status() -> str:
144144 assert attempts ["count" ] == 1
145145
146146
147+ def test_poll_until_terminal_status_retries_overlong_numeric_status_codes ():
148+ attempts = {"count" : 0 }
149+
150+ def get_status () -> str :
151+ attempts ["count" ] += 1
152+ if attempts ["count" ] < 3 :
153+ raise HyperbrowserError (
154+ "oversized status metadata" ,
155+ status_code = "4000000000000" , # type: ignore[arg-type]
156+ )
157+ return "completed"
158+
159+ status = poll_until_terminal_status (
160+ operation_name = "sync poll oversized numeric status retries" ,
161+ get_status = get_status ,
162+ is_terminal_status = lambda value : value == "completed" ,
163+ poll_interval_seconds = 0.0001 ,
164+ max_wait_seconds = 1.0 ,
165+ max_status_failures = 5 ,
166+ )
167+
168+ assert status == "completed"
169+ assert attempts ["count" ] == 3
170+
171+
147172def test_poll_until_terminal_status_does_not_retry_stop_iteration_errors ():
148173 attempts = {"count" : 0 }
149174
@@ -602,6 +627,27 @@ def operation() -> str:
602627 assert attempts ["count" ] == 3
603628
604629
630+ def test_retry_operation_does_not_retry_numeric_bytes_client_errors ():
631+ attempts = {"count" : 0 }
632+
633+ def operation () -> str :
634+ attempts ["count" ] += 1
635+ raise HyperbrowserError (
636+ "client failure" ,
637+ status_code = b"400" , # type: ignore[arg-type]
638+ )
639+
640+ with pytest .raises (HyperbrowserError , match = "client failure" ):
641+ retry_operation (
642+ operation_name = "sync retry numeric-bytes client error" ,
643+ operation = operation ,
644+ max_attempts = 5 ,
645+ retry_delay_seconds = 0.0001 ,
646+ )
647+
648+ assert attempts ["count" ] == 1
649+
650+
605651def test_retry_operation_does_not_retry_stop_iteration_errors ():
606652 attempts = {"count" : 0 }
607653
@@ -951,6 +997,34 @@ async def get_status() -> str:
951997 asyncio .run (run ())
952998
953999
1000+ def test_poll_until_terminal_status_async_retries_overlong_numeric_status_codes ():
1001+ async def run () -> None :
1002+ attempts = {"count" : 0 }
1003+
1004+ async def get_status () -> str :
1005+ attempts ["count" ] += 1
1006+ if attempts ["count" ] < 3 :
1007+ raise HyperbrowserError (
1008+ "oversized status metadata" ,
1009+ status_code = "4000000000000" , # type: ignore[arg-type]
1010+ )
1011+ return "completed"
1012+
1013+ status = await poll_until_terminal_status_async (
1014+ operation_name = "async poll oversized numeric status retries" ,
1015+ get_status = get_status ,
1016+ is_terminal_status = lambda value : value == "completed" ,
1017+ poll_interval_seconds = 0.0001 ,
1018+ max_wait_seconds = 1.0 ,
1019+ max_status_failures = 5 ,
1020+ )
1021+
1022+ assert status == "completed"
1023+ assert attempts ["count" ] == 3
1024+
1025+ asyncio .run (run ())
1026+
1027+
9541028def test_poll_until_terminal_status_async_does_not_retry_stop_async_iteration_errors ():
9551029 async def run () -> None :
9561030 attempts = {"count" : 0 }
@@ -1181,6 +1255,32 @@ async def operation() -> str:
11811255 asyncio .run (run ())
11821256
11831257
1258+ def test_retry_operation_async_retries_numeric_bytes_rate_limit_errors ():
1259+ async def run () -> None :
1260+ attempts = {"count" : 0 }
1261+
1262+ async def operation () -> str :
1263+ attempts ["count" ] += 1
1264+ if attempts ["count" ] < 3 :
1265+ raise HyperbrowserError (
1266+ "rate limited" ,
1267+ status_code = b"429" , # type: ignore[arg-type]
1268+ )
1269+ return "ok"
1270+
1271+ result = await retry_operation_async (
1272+ operation_name = "async retry numeric-bytes rate limit" ,
1273+ operation = operation ,
1274+ max_attempts = 5 ,
1275+ retry_delay_seconds = 0.0001 ,
1276+ )
1277+
1278+ assert result == "ok"
1279+ assert attempts ["count" ] == 3
1280+
1281+ asyncio .run (run ())
1282+
1283+
11841284def test_retry_operation_async_does_not_retry_stop_async_iteration_errors ():
11851285 async def run () -> None :
11861286 attempts = {"count" : 0 }
0 commit comments