@@ -6744,6 +6744,32 @@ def __str__(self) -> str:
67446744 )
67456745
67466746
6747+ def test_poll_until_terminal_status_handles_runtime_errors_with_broken_string_subclasses ():
6748+ class _BrokenRenderedRuntimeError (RuntimeError ):
6749+ class _BrokenString (str ):
6750+ def __iter__ (self ):
6751+ raise RuntimeError ("cannot iterate rendered runtime message" )
6752+
6753+ def __str__ (self ) -> str :
6754+ return self ._BrokenString ("broken runtime message" )
6755+
6756+ with pytest .raises (
6757+ HyperbrowserPollingError ,
6758+ match = (
6759+ r"Failed to poll sync poll after 1 attempts: "
6760+ r"<unstringifiable _BrokenRenderedRuntimeError>"
6761+ ),
6762+ ):
6763+ poll_until_terminal_status (
6764+ operation_name = "sync poll" ,
6765+ get_status = lambda : (_ for _ in ()).throw (_BrokenRenderedRuntimeError ()),
6766+ is_terminal_status = lambda value : value == "completed" ,
6767+ poll_interval_seconds = 0.0 ,
6768+ max_wait_seconds = 1.0 ,
6769+ max_status_failures = 1 ,
6770+ )
6771+
6772+
67476773def test_retry_operation_handles_unstringifiable_value_errors ():
67486774 class _UnstringifiableValueError (ValueError ):
67496775 def __str__ (self ) -> str :
@@ -6764,6 +6790,30 @@ def __str__(self) -> str:
67646790 )
67656791
67666792
6793+ def test_retry_operation_handles_value_errors_with_broken_string_subclasses ():
6794+ class _BrokenRenderedValueError (ValueError ):
6795+ class _BrokenString (str ):
6796+ def __iter__ (self ):
6797+ raise RuntimeError ("cannot iterate rendered value message" )
6798+
6799+ def __str__ (self ) -> str :
6800+ return self ._BrokenString ("broken value message" )
6801+
6802+ with pytest .raises (
6803+ HyperbrowserError ,
6804+ match = (
6805+ r"sync retry failed after 1 attempts: "
6806+ r"<unstringifiable _BrokenRenderedValueError>"
6807+ ),
6808+ ):
6809+ retry_operation (
6810+ operation_name = "sync retry" ,
6811+ operation = lambda : (_ for _ in ()).throw (_BrokenRenderedValueError ()),
6812+ max_attempts = 1 ,
6813+ retry_delay_seconds = 0.0 ,
6814+ )
6815+
6816+
67676817def test_poll_until_terminal_status_handles_unstringifiable_callback_errors ():
67686818 class _UnstringifiableCallbackError (RuntimeError ):
67696819 def __str__ (self ) -> str :
@@ -6788,6 +6838,34 @@ def __str__(self) -> str:
67886838 )
67896839
67906840
6841+ def test_poll_until_terminal_status_handles_callback_errors_with_broken_string_subclasses ():
6842+ class _BrokenRenderedCallbackError (RuntimeError ):
6843+ class _BrokenString (str ):
6844+ def __iter__ (self ):
6845+ raise RuntimeError ("cannot iterate rendered callback message" )
6846+
6847+ def __str__ (self ) -> str :
6848+ return self ._BrokenString ("broken callback message" )
6849+
6850+ with pytest .raises (
6851+ HyperbrowserError ,
6852+ match = (
6853+ r"is_terminal_status failed for callback poll: "
6854+ r"<unstringifiable _BrokenRenderedCallbackError>"
6855+ ),
6856+ ):
6857+ poll_until_terminal_status (
6858+ operation_name = "callback poll" ,
6859+ get_status = lambda : "running" ,
6860+ is_terminal_status = lambda value : (_ for _ in ()).throw (
6861+ _BrokenRenderedCallbackError ()
6862+ ),
6863+ poll_interval_seconds = 0.0 ,
6864+ max_wait_seconds = 1.0 ,
6865+ max_status_failures = 1 ,
6866+ )
6867+
6868+
67916869def test_poll_until_terminal_status_uses_placeholder_for_blank_error_messages ():
67926870 with pytest .raises (
67936871 HyperbrowserPollingError ,
0 commit comments