@@ -53,3 +53,48 @@ def test_hyperbrowser_error_str_truncates_oversized_original_error_message():
5353 rendered_error = str (error )
5454 assert "Caused by ValueError:" in rendered_error
5555 assert rendered_error .endswith ("... (truncated)" )
56+
57+
58+ def test_hyperbrowser_error_str_handles_message_string_subclass_iteration_failures ():
59+ class _BrokenMessage :
60+ class _BrokenString (str ):
61+ def __iter__ (self ):
62+ raise RuntimeError ("cannot iterate error message" )
63+
64+ def __str__ (self ) -> str :
65+ return self ._BrokenString ("request failed" )
66+
67+ error = HyperbrowserError (_BrokenMessage ()) # type: ignore[arg-type]
68+
69+ assert str (error ) == "Hyperbrowser error"
70+
71+
72+ def test_hyperbrowser_error_str_handles_status_string_subclass_iteration_failures ():
73+ class _BrokenStatus :
74+ class _BrokenString (str ):
75+ def __iter__ (self ):
76+ raise RuntimeError ("cannot iterate status text" )
77+
78+ def __str__ (self ) -> str :
79+ return self ._BrokenString ("status\t value" )
80+
81+ error = HyperbrowserError ("request failed" , status_code = _BrokenStatus ()) # type: ignore[arg-type]
82+
83+ assert str (error ) == "request failed - Status: <unknown status>"
84+
85+
86+ def test_hyperbrowser_error_str_handles_original_error_string_subclass_iteration_failures ():
87+ class _BrokenOriginalError (Exception ):
88+ class _BrokenString (str ):
89+ def __iter__ (self ):
90+ raise RuntimeError ("cannot iterate original error text" )
91+
92+ def __str__ (self ) -> str :
93+ return self ._BrokenString ("bad\t cause" )
94+
95+ error = HyperbrowserError ("request failed" , original_error = _BrokenOriginalError ())
96+
97+ assert (
98+ str (error )
99+ == "request failed - Caused by _BrokenOriginalError: <unstringifiable _BrokenOriginalError>"
100+ )
0 commit comments