Skip to content

Commit 6db6de4

Browse files
committed
fix: use strict key access in GitHub API shape validation
Replace data.get('resources', {}).get('core', {}) with direct key access data['resources']['core'] inside the try/except block so that a missing key raises KeyError and is caught as malformed_response — matching the comment. Add test_missing_resources_key to cover this path. Addresses CodeRabbit review feedback (round 3).
1 parent 82fa9b9 commit 6db6de4

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

backend/app/api/health.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ async def _check_github_api() -> dict:
169169
data = resp.json()
170170
if not isinstance(data, dict):
171171
raise ValueError(f"unexpected response type: {type(data)}")
172-
# Validate expected shape; missing keys return empty dicts
173-
_ = data.get("resources", {}).get("core", {})
172+
# Validate expected shape; KeyError raised here if keys missing.
173+
_ = data["resources"]["core"]
174174
except Exception as exc:
175175
logger.warning("GitHub API malformed response: %s", exc)
176176
latency_ms = round((time.monotonic() - start) * 1000)
@@ -283,3 +283,4 @@ async def health_check() -> dict:
283283
"timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
284284
"services": services,
285285
}
286+

backend/tests/test_health.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,23 @@ def test_malformed_response(self):
449449
assert result["status"] == "degraded"
450450
assert result["error"] == "malformed_response"
451451

452+
def test_missing_resources_key(self):
453+
"""Response missing 'resources' key should return degraded with malformed_response."""
454+
mock_resp = MagicMock(spec=Response)
455+
mock_resp.status_code = 200
456+
mock_resp.raise_for_status = MagicMock()
457+
mock_resp.json.return_value = {"unexpected": "shape"}
458+
459+
mock_client = AsyncMock()
460+
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
461+
mock_client.__aexit__ = AsyncMock(return_value=False)
462+
mock_client.get = AsyncMock(return_value=mock_resp)
463+
464+
with patch("app.api.health.httpx.AsyncClient", return_value=mock_client):
465+
result = run_async(_check_github_api())
466+
assert result["status"] == "degraded"
467+
assert result["error"] == "malformed_response"
468+
452469
def test_http_status_error(self):
453470
"""Non-2xx GitHub responses (e.g. 403, 500) return degraded with http_<code> error."""
454471
from httpx import HTTPStatusError, Request as HttpxRequest

0 commit comments

Comments
 (0)