@@ -3310,6 +3310,38 @@ def fetch_result() -> dict:
33103310 assert fetch_attempts ["count" ] == 0
33113311
33123312
3313+ def test_wait_for_job_result_does_not_retry_numeric_string_status_errors ():
3314+ status_attempts = {"count" : 0 }
3315+ fetch_attempts = {"count" : 0 }
3316+
3317+ def get_status () -> str :
3318+ status_attempts ["count" ] += 1
3319+ raise HyperbrowserError (
3320+ "client failure" ,
3321+ status_code = "400" , # type: ignore[arg-type]
3322+ )
3323+
3324+ def fetch_result () -> dict :
3325+ fetch_attempts ["count" ] += 1
3326+ return {"ok" : True }
3327+
3328+ with pytest .raises (HyperbrowserError , match = "client failure" ):
3329+ wait_for_job_result (
3330+ operation_name = "sync wait helper status numeric-string client error" ,
3331+ get_status = get_status ,
3332+ is_terminal_status = lambda value : value == "completed" ,
3333+ fetch_result = fetch_result ,
3334+ poll_interval_seconds = 0.0001 ,
3335+ max_wait_seconds = 1.0 ,
3336+ max_status_failures = 5 ,
3337+ fetch_max_attempts = 5 ,
3338+ fetch_retry_delay_seconds = 0.0001 ,
3339+ )
3340+
3341+ assert status_attempts ["count" ] == 1
3342+ assert fetch_attempts ["count" ] == 0
3343+
3344+
33133345def test_wait_for_job_result_does_not_retry_broken_executor_status_errors ():
33143346 status_attempts = {"count" : 0 }
33153347 fetch_attempts = {"count" : 0 }
@@ -3827,6 +3859,34 @@ def fetch_result() -> dict:
38273859 assert fetch_attempts ["count" ] == 3
38283860
38293861
3862+ def test_wait_for_job_result_retries_numeric_string_rate_limit_fetch_errors ():
3863+ fetch_attempts = {"count" : 0 }
3864+
3865+ def fetch_result () -> dict :
3866+ fetch_attempts ["count" ] += 1
3867+ if fetch_attempts ["count" ] < 3 :
3868+ raise HyperbrowserError (
3869+ "rate limited" ,
3870+ status_code = "429" , # type: ignore[arg-type]
3871+ )
3872+ return {"ok" : True }
3873+
3874+ result = wait_for_job_result (
3875+ operation_name = "sync wait helper fetch numeric-string rate limit" ,
3876+ get_status = lambda : "completed" ,
3877+ is_terminal_status = lambda value : value == "completed" ,
3878+ fetch_result = fetch_result ,
3879+ poll_interval_seconds = 0.0001 ,
3880+ max_wait_seconds = 1.0 ,
3881+ max_status_failures = 5 ,
3882+ fetch_max_attempts = 5 ,
3883+ fetch_retry_delay_seconds = 0.0001 ,
3884+ )
3885+
3886+ assert result == {"ok" : True }
3887+ assert fetch_attempts ["count" ] == 3
3888+
3889+
38303890def test_wait_for_job_result_retries_request_timeout_fetch_errors ():
38313891 fetch_attempts = {"count" : 0 }
38323892
@@ -3969,6 +4029,41 @@ async def fetch_result() -> dict:
39694029 asyncio .run (run ())
39704030
39714031
4032+ def test_wait_for_job_result_async_does_not_retry_numeric_string_status_errors ():
4033+ async def run () -> None :
4034+ status_attempts = {"count" : 0 }
4035+ fetch_attempts = {"count" : 0 }
4036+
4037+ async def get_status () -> str :
4038+ status_attempts ["count" ] += 1
4039+ raise HyperbrowserError (
4040+ "client failure" ,
4041+ status_code = "404" , # type: ignore[arg-type]
4042+ )
4043+
4044+ async def fetch_result () -> dict :
4045+ fetch_attempts ["count" ] += 1
4046+ return {"ok" : True }
4047+
4048+ with pytest .raises (HyperbrowserError , match = "client failure" ):
4049+ await wait_for_job_result_async (
4050+ operation_name = "async wait helper status numeric-string client error" ,
4051+ get_status = get_status ,
4052+ is_terminal_status = lambda value : value == "completed" ,
4053+ fetch_result = fetch_result ,
4054+ poll_interval_seconds = 0.0001 ,
4055+ max_wait_seconds = 1.0 ,
4056+ max_status_failures = 5 ,
4057+ fetch_max_attempts = 5 ,
4058+ fetch_retry_delay_seconds = 0.0001 ,
4059+ )
4060+
4061+ assert status_attempts ["count" ] == 1
4062+ assert fetch_attempts ["count" ] == 0
4063+
4064+ asyncio .run (run ())
4065+
4066+
39724067def test_wait_for_job_result_async_does_not_retry_broken_executor_status_errors ():
39734068 async def run () -> None :
39744069 status_attempts = {"count" : 0 }
@@ -4534,6 +4629,37 @@ async def fetch_result() -> dict:
45344629 asyncio .run (run ())
45354630
45364631
4632+ def test_wait_for_job_result_async_retries_numeric_string_rate_limit_fetch_errors ():
4633+ async def run () -> None :
4634+ fetch_attempts = {"count" : 0 }
4635+
4636+ async def fetch_result () -> dict :
4637+ fetch_attempts ["count" ] += 1
4638+ if fetch_attempts ["count" ] < 3 :
4639+ raise HyperbrowserError (
4640+ "rate limited" ,
4641+ status_code = " 429 " , # type: ignore[arg-type]
4642+ )
4643+ return {"ok" : True }
4644+
4645+ result = await wait_for_job_result_async (
4646+ operation_name = "async wait helper fetch numeric-string rate limit" ,
4647+ get_status = lambda : asyncio .sleep (0 , result = "completed" ),
4648+ is_terminal_status = lambda value : value == "completed" ,
4649+ fetch_result = fetch_result ,
4650+ poll_interval_seconds = 0.0001 ,
4651+ max_wait_seconds = 1.0 ,
4652+ max_status_failures = 5 ,
4653+ fetch_max_attempts = 5 ,
4654+ fetch_retry_delay_seconds = 0.0001 ,
4655+ )
4656+
4657+ assert result == {"ok" : True }
4658+ assert fetch_attempts ["count" ] == 3
4659+
4660+ asyncio .run (run ())
4661+
4662+
45374663def test_wait_for_job_result_async_retries_request_timeout_fetch_errors ():
45384664 async def run () -> None :
45394665 fetch_attempts = {"count" : 0 }
0 commit comments