diff --git a/strix/config/grok.py b/strix/config/grok.py index e047a5e8..1cbe5d35 100644 --- a/strix/config/grok.py +++ b/strix/config/grok.py @@ -157,19 +157,23 @@ def _first(query: dict[str, list[str]], key: str) -> str | None: def _post_form(payload: dict[str, str]) -> dict[str, Any]: + detail = "" try: - response = requests.post( + with requests.post( TOKEN_URL, data=payload, headers={"Accept": "application/json"}, timeout=_TOKEN_TIMEOUT, - ) + ) as response: + status_code = response.status_code + body = response.content + if status_code >= 400: + detail = response.text[:300] except requests.RequestException as exc: raise GrokAuthError("unavailable", str(exc)) from exc - if response.status_code >= 400: - detail = response.text[:300] - raise GrokAuthError("token_http_error", f"HTTP {response.status_code}: {detail}") - data = json.loads(response.content or b"{}") + if status_code >= 400: + raise GrokAuthError("token_http_error", f"HTTP {status_code}: {detail}") + data = json.loads(body or b"{}") if not isinstance(data, dict): raise GrokAuthError("bad_response", "token endpoint returned non-object") return data diff --git a/tests/test_grok_auth.py b/tests/test_grok_auth.py index a8c75d43..9002c97e 100644 --- a/tests/test_grok_auth.py +++ b/tests/test_grok_auth.py @@ -56,6 +56,7 @@ def test_post_form_returns_parsed_body() -> None: resp = mock.MagicMock() resp.status_code = 200 resp.content = b'{"access_token": "tok"}' + resp.__enter__.return_value = resp with mock.patch.object(requests, "post", return_value=resp) as post: data = grok._post_form({"grant_type": "refresh_token"}) @@ -68,6 +69,7 @@ def test_post_form_raises_on_http_error() -> None: resp = mock.MagicMock() resp.status_code = 400 resp.text = "invalid_grant" + resp.__enter__.return_value = resp with ( mock.patch.object(requests, "post", return_value=resp),