Skip to content

Commit a1482b1

Browse files
Wrap client api_key strip normalization failures
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 8f0ba93 commit a1482b1

2 files changed

Lines changed: 51 additions & 1 deletion

File tree

hyperbrowser/client/base.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,18 @@ def __init__(
3838
)
3939
if not isinstance(resolved_api_key, str):
4040
raise HyperbrowserError("api_key must be a string")
41-
if not resolved_api_key.strip():
41+
try:
42+
normalized_resolved_api_key = resolved_api_key.strip()
43+
if not isinstance(normalized_resolved_api_key, str):
44+
raise TypeError("normalized api_key must be a string")
45+
except HyperbrowserError:
46+
raise
47+
except Exception as exc:
48+
raise HyperbrowserError(
49+
"Failed to normalize api_key",
50+
original_error=exc,
51+
) from exc
52+
if not normalized_resolved_api_key:
4253
if api_key_from_constructor:
4354
raise HyperbrowserError("api_key must not be empty")
4455
raise HyperbrowserError(

tests/test_client_api_key.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,42 @@ def test_async_client_rejects_control_character_env_api_key(monkeypatch):
108108
HyperbrowserError, match="api_key must not contain control characters"
109109
):
110110
AsyncHyperbrowser()
111+
112+
113+
@pytest.mark.parametrize("client_class", [Hyperbrowser, AsyncHyperbrowser])
114+
def test_client_wraps_api_key_strip_runtime_errors(client_class):
115+
class _BrokenStripApiKey(str):
116+
def strip(self, chars=None): # type: ignore[override]
117+
_ = chars
118+
raise RuntimeError("api key strip exploded")
119+
120+
with pytest.raises(HyperbrowserError, match="Failed to normalize api_key") as exc_info:
121+
client_class(api_key=_BrokenStripApiKey("test-key"))
122+
123+
assert isinstance(exc_info.value.original_error, RuntimeError)
124+
125+
126+
@pytest.mark.parametrize("client_class", [Hyperbrowser, AsyncHyperbrowser])
127+
def test_client_preserves_hyperbrowser_api_key_strip_errors(client_class):
128+
class _BrokenStripApiKey(str):
129+
def strip(self, chars=None): # type: ignore[override]
130+
_ = chars
131+
raise HyperbrowserError("custom strip failure")
132+
133+
with pytest.raises(HyperbrowserError, match="custom strip failure") as exc_info:
134+
client_class(api_key=_BrokenStripApiKey("test-key"))
135+
136+
assert exc_info.value.original_error is None
137+
138+
139+
@pytest.mark.parametrize("client_class", [Hyperbrowser, AsyncHyperbrowser])
140+
def test_client_wraps_non_string_api_key_strip_results(client_class):
141+
class _NonStringStripResultApiKey(str):
142+
def strip(self, chars=None): # type: ignore[override]
143+
_ = chars
144+
return object()
145+
146+
with pytest.raises(HyperbrowserError, match="Failed to normalize api_key") as exc_info:
147+
client_class(api_key=_NonStringStripResultApiKey("test-key"))
148+
149+
assert isinstance(exc_info.value.original_error, TypeError)

0 commit comments

Comments
 (0)