@@ -122,6 +122,44 @@ def get_status() -> str:
122122 assert attempts ["count" ] == 1
123123
124124
125+ def test_poll_until_terminal_status_does_not_retry_timeout_or_polling_errors ():
126+ timeout_attempts = {"count" : 0 }
127+
128+ def get_status_timeout () -> str :
129+ timeout_attempts ["count" ] += 1
130+ raise HyperbrowserTimeoutError ("timed out internally" )
131+
132+ with pytest .raises (HyperbrowserTimeoutError , match = "timed out internally" ):
133+ poll_until_terminal_status (
134+ operation_name = "sync poll timeout passthrough" ,
135+ get_status = get_status_timeout ,
136+ is_terminal_status = lambda value : value == "completed" ,
137+ poll_interval_seconds = 0.0001 ,
138+ max_wait_seconds = 1.0 ,
139+ max_status_failures = 5 ,
140+ )
141+
142+ assert timeout_attempts ["count" ] == 1
143+
144+ polling_attempts = {"count" : 0 }
145+
146+ def get_status_polling_error () -> str :
147+ polling_attempts ["count" ] += 1
148+ raise HyperbrowserPollingError ("upstream polling failure" )
149+
150+ with pytest .raises (HyperbrowserPollingError , match = "upstream polling failure" ):
151+ poll_until_terminal_status (
152+ operation_name = "sync poll polling-error passthrough" ,
153+ get_status = get_status_polling_error ,
154+ is_terminal_status = lambda value : value == "completed" ,
155+ poll_interval_seconds = 0.0001 ,
156+ max_wait_seconds = 1.0 ,
157+ max_status_failures = 5 ,
158+ )
159+
160+ assert polling_attempts ["count" ] == 1
161+
162+
125163def test_poll_until_terminal_status_retries_rate_limit_errors ():
126164 attempts = {"count" : 0 }
127165
@@ -325,6 +363,40 @@ def operation() -> str:
325363 assert attempts ["count" ] == 1
326364
327365
366+ def test_retry_operation_does_not_retry_timeout_or_polling_errors ():
367+ timeout_attempts = {"count" : 0 }
368+
369+ def timeout_operation () -> str :
370+ timeout_attempts ["count" ] += 1
371+ raise HyperbrowserTimeoutError ("timed out internally" )
372+
373+ with pytest .raises (HyperbrowserTimeoutError , match = "timed out internally" ):
374+ retry_operation (
375+ operation_name = "sync retry timeout passthrough" ,
376+ operation = timeout_operation ,
377+ max_attempts = 5 ,
378+ retry_delay_seconds = 0.0001 ,
379+ )
380+
381+ assert timeout_attempts ["count" ] == 1
382+
383+ polling_attempts = {"count" : 0 }
384+
385+ def polling_error_operation () -> str :
386+ polling_attempts ["count" ] += 1
387+ raise HyperbrowserPollingError ("upstream polling failure" )
388+
389+ with pytest .raises (HyperbrowserPollingError , match = "upstream polling failure" ):
390+ retry_operation (
391+ operation_name = "sync retry polling-error passthrough" ,
392+ operation = polling_error_operation ,
393+ max_attempts = 5 ,
394+ retry_delay_seconds = 0.0001 ,
395+ )
396+
397+ assert polling_attempts ["count" ] == 1
398+
399+
328400def test_retry_operation_retries_server_errors ():
329401 attempts = {"count" : 0 }
330402
@@ -481,6 +553,47 @@ async def get_status() -> str:
481553 asyncio .run (run ())
482554
483555
556+ def test_poll_until_terminal_status_async_does_not_retry_timeout_or_polling_errors ():
557+ async def run () -> None :
558+ timeout_attempts = {"count" : 0 }
559+
560+ async def get_status_timeout () -> str :
561+ timeout_attempts ["count" ] += 1
562+ raise HyperbrowserTimeoutError ("timed out internally" )
563+
564+ with pytest .raises (HyperbrowserTimeoutError , match = "timed out internally" ):
565+ await poll_until_terminal_status_async (
566+ operation_name = "async poll timeout passthrough" ,
567+ get_status = get_status_timeout ,
568+ is_terminal_status = lambda value : value == "completed" ,
569+ poll_interval_seconds = 0.0001 ,
570+ max_wait_seconds = 1.0 ,
571+ max_status_failures = 5 ,
572+ )
573+
574+ assert timeout_attempts ["count" ] == 1
575+
576+ polling_attempts = {"count" : 0 }
577+
578+ async def get_status_polling_error () -> str :
579+ polling_attempts ["count" ] += 1
580+ raise HyperbrowserPollingError ("upstream polling failure" )
581+
582+ with pytest .raises (HyperbrowserPollingError , match = "upstream polling failure" ):
583+ await poll_until_terminal_status_async (
584+ operation_name = "async poll polling-error passthrough" ,
585+ get_status = get_status_polling_error ,
586+ is_terminal_status = lambda value : value == "completed" ,
587+ poll_interval_seconds = 0.0001 ,
588+ max_wait_seconds = 1.0 ,
589+ max_status_failures = 5 ,
590+ )
591+
592+ assert polling_attempts ["count" ] == 1
593+
594+ asyncio .run (run ())
595+
596+
484597def test_poll_until_terminal_status_async_retries_server_errors ():
485598 async def run () -> None :
486599 attempts = {"count" : 0 }
@@ -552,6 +665,43 @@ async def operation() -> str:
552665 asyncio .run (run ())
553666
554667
668+ def test_retry_operation_async_does_not_retry_timeout_or_polling_errors ():
669+ async def run () -> None :
670+ timeout_attempts = {"count" : 0 }
671+
672+ async def timeout_operation () -> str :
673+ timeout_attempts ["count" ] += 1
674+ raise HyperbrowserTimeoutError ("timed out internally" )
675+
676+ with pytest .raises (HyperbrowserTimeoutError , match = "timed out internally" ):
677+ await retry_operation_async (
678+ operation_name = "async retry timeout passthrough" ,
679+ operation = timeout_operation ,
680+ max_attempts = 5 ,
681+ retry_delay_seconds = 0.0001 ,
682+ )
683+
684+ assert timeout_attempts ["count" ] == 1
685+
686+ polling_attempts = {"count" : 0 }
687+
688+ async def polling_error_operation () -> str :
689+ polling_attempts ["count" ] += 1
690+ raise HyperbrowserPollingError ("upstream polling failure" )
691+
692+ with pytest .raises (HyperbrowserPollingError , match = "upstream polling failure" ):
693+ await retry_operation_async (
694+ operation_name = "async retry polling-error passthrough" ,
695+ operation = polling_error_operation ,
696+ max_attempts = 5 ,
697+ retry_delay_seconds = 0.0001 ,
698+ )
699+
700+ assert polling_attempts ["count" ] == 1
701+
702+ asyncio .run (run ())
703+
704+
555705def test_retry_operation_async_retries_server_errors ():
556706 async def run () -> None :
557707 attempts = {"count" : 0 }
@@ -1125,6 +1275,28 @@ def get_next_page(page: int) -> dict:
11251275 assert attempts ["count" ] == 1
11261276
11271277
1278+ def test_collect_paginated_results_does_not_retry_timeout_errors ():
1279+ attempts = {"count" : 0 }
1280+
1281+ def get_next_page (page : int ) -> dict :
1282+ attempts ["count" ] += 1
1283+ raise HyperbrowserTimeoutError ("timed out internally" )
1284+
1285+ with pytest .raises (HyperbrowserTimeoutError , match = "timed out internally" ):
1286+ collect_paginated_results (
1287+ operation_name = "sync paginated timeout passthrough" ,
1288+ get_next_page = get_next_page ,
1289+ get_current_page_batch = lambda response : response ["current" ],
1290+ get_total_page_batches = lambda response : response ["total" ],
1291+ on_page_success = lambda response : None ,
1292+ max_wait_seconds = 1.0 ,
1293+ max_attempts = 5 ,
1294+ retry_delay_seconds = 0.0001 ,
1295+ )
1296+
1297+ assert attempts ["count" ] == 1
1298+
1299+
11281300def test_collect_paginated_results_retries_server_errors ():
11291301 attempts = {"count" : 0 }
11301302 collected = []
@@ -1366,6 +1538,31 @@ async def get_next_page(page: int) -> dict:
13661538 asyncio .run (run ())
13671539
13681540
1541+ def test_collect_paginated_results_async_does_not_retry_timeout_errors ():
1542+ async def run () -> None :
1543+ attempts = {"count" : 0 }
1544+
1545+ async def get_next_page (page : int ) -> dict :
1546+ attempts ["count" ] += 1
1547+ raise HyperbrowserTimeoutError ("timed out internally" )
1548+
1549+ with pytest .raises (HyperbrowserTimeoutError , match = "timed out internally" ):
1550+ await collect_paginated_results_async (
1551+ operation_name = "async paginated timeout passthrough" ,
1552+ get_next_page = get_next_page ,
1553+ get_current_page_batch = lambda response : response ["current" ],
1554+ get_total_page_batches = lambda response : response ["total" ],
1555+ on_page_success = lambda response : None ,
1556+ max_wait_seconds = 1.0 ,
1557+ max_attempts = 5 ,
1558+ retry_delay_seconds = 0.0001 ,
1559+ )
1560+
1561+ assert attempts ["count" ] == 1
1562+
1563+ asyncio .run (run ())
1564+
1565+
13691566def test_collect_paginated_results_async_retries_server_errors ():
13701567 async def run () -> None :
13711568 attempts = {"count" : 0 }
0 commit comments