@@ -2369,6 +2369,66 @@ def test_wait_for_job_result_returns_fetched_value():
23692369 assert result == {"ok" : True }
23702370
23712371
2372+ def test_wait_for_job_result_does_not_retry_non_retryable_status_errors ():
2373+ status_attempts = {"count" : 0 }
2374+ fetch_attempts = {"count" : 0 }
2375+
2376+ def get_status () -> str :
2377+ status_attempts ["count" ] += 1
2378+ raise HyperbrowserError ("client failure" , status_code = 400 )
2379+
2380+ def fetch_result () -> dict :
2381+ fetch_attempts ["count" ] += 1
2382+ return {"ok" : True }
2383+
2384+ with pytest .raises (HyperbrowserError , match = "client failure" ):
2385+ wait_for_job_result (
2386+ operation_name = "sync wait helper status client error" ,
2387+ get_status = get_status ,
2388+ is_terminal_status = lambda value : value == "completed" ,
2389+ fetch_result = fetch_result ,
2390+ poll_interval_seconds = 0.0001 ,
2391+ max_wait_seconds = 1.0 ,
2392+ max_status_failures = 5 ,
2393+ fetch_max_attempts = 5 ,
2394+ fetch_retry_delay_seconds = 0.0001 ,
2395+ )
2396+
2397+ assert status_attempts ["count" ] == 1
2398+ assert fetch_attempts ["count" ] == 0
2399+
2400+
2401+ def test_wait_for_job_result_retries_rate_limit_status_errors ():
2402+ status_attempts = {"count" : 0 }
2403+ fetch_attempts = {"count" : 0 }
2404+
2405+ def get_status () -> str :
2406+ status_attempts ["count" ] += 1
2407+ if status_attempts ["count" ] < 3 :
2408+ raise HyperbrowserError ("rate limited" , status_code = 429 )
2409+ return "completed"
2410+
2411+ def fetch_result () -> dict :
2412+ fetch_attempts ["count" ] += 1
2413+ return {"ok" : True }
2414+
2415+ result = wait_for_job_result (
2416+ operation_name = "sync wait helper status rate-limit retries" ,
2417+ get_status = get_status ,
2418+ is_terminal_status = lambda value : value == "completed" ,
2419+ fetch_result = fetch_result ,
2420+ poll_interval_seconds = 0.0001 ,
2421+ max_wait_seconds = 1.0 ,
2422+ max_status_failures = 5 ,
2423+ fetch_max_attempts = 5 ,
2424+ fetch_retry_delay_seconds = 0.0001 ,
2425+ )
2426+
2427+ assert result == {"ok" : True }
2428+ assert status_attempts ["count" ] == 3
2429+ assert fetch_attempts ["count" ] == 1
2430+
2431+
23722432def test_wait_for_job_result_does_not_retry_non_retryable_fetch_errors ():
23732433 fetch_attempts = {"count" : 0 }
23742434
@@ -2463,6 +2523,72 @@ async def run() -> None:
24632523 asyncio .run (run ())
24642524
24652525
2526+ def test_wait_for_job_result_async_does_not_retry_non_retryable_status_errors ():
2527+ async def run () -> None :
2528+ status_attempts = {"count" : 0 }
2529+ fetch_attempts = {"count" : 0 }
2530+
2531+ async def get_status () -> str :
2532+ status_attempts ["count" ] += 1
2533+ raise HyperbrowserError ("client failure" , status_code = 404 )
2534+
2535+ async def fetch_result () -> dict :
2536+ fetch_attempts ["count" ] += 1
2537+ return {"ok" : True }
2538+
2539+ with pytest .raises (HyperbrowserError , match = "client failure" ):
2540+ await wait_for_job_result_async (
2541+ operation_name = "async wait helper status client error" ,
2542+ get_status = get_status ,
2543+ is_terminal_status = lambda value : value == "completed" ,
2544+ fetch_result = fetch_result ,
2545+ poll_interval_seconds = 0.0001 ,
2546+ max_wait_seconds = 1.0 ,
2547+ max_status_failures = 5 ,
2548+ fetch_max_attempts = 5 ,
2549+ fetch_retry_delay_seconds = 0.0001 ,
2550+ )
2551+
2552+ assert status_attempts ["count" ] == 1
2553+ assert fetch_attempts ["count" ] == 0
2554+
2555+ asyncio .run (run ())
2556+
2557+
2558+ def test_wait_for_job_result_async_retries_rate_limit_status_errors ():
2559+ async def run () -> None :
2560+ status_attempts = {"count" : 0 }
2561+ fetch_attempts = {"count" : 0 }
2562+
2563+ async def get_status () -> str :
2564+ status_attempts ["count" ] += 1
2565+ if status_attempts ["count" ] < 3 :
2566+ raise HyperbrowserError ("rate limited" , status_code = 429 )
2567+ return "completed"
2568+
2569+ async def fetch_result () -> dict :
2570+ fetch_attempts ["count" ] += 1
2571+ return {"ok" : True }
2572+
2573+ result = await wait_for_job_result_async (
2574+ operation_name = "async wait helper status rate-limit retries" ,
2575+ get_status = get_status ,
2576+ is_terminal_status = lambda value : value == "completed" ,
2577+ fetch_result = fetch_result ,
2578+ poll_interval_seconds = 0.0001 ,
2579+ max_wait_seconds = 1.0 ,
2580+ max_status_failures = 5 ,
2581+ fetch_max_attempts = 5 ,
2582+ fetch_retry_delay_seconds = 0.0001 ,
2583+ )
2584+
2585+ assert result == {"ok" : True }
2586+ assert status_attempts ["count" ] == 3
2587+ assert fetch_attempts ["count" ] == 1
2588+
2589+ asyncio .run (run ())
2590+
2591+
24662592def test_wait_for_job_result_async_does_not_retry_non_retryable_fetch_errors ():
24672593 async def run () -> None :
24682594 fetch_attempts = {"count" : 0 }
0 commit comments