Skip to content

fix: handle non-JSON error response bodies in _error_body (#242)#274

Merged
thodson-usgs merged 3 commits into
DOI-USGS:mainfrom
SAY-5:fix/issue-242-error-body-non-json
May 12, 2026
Merged

fix: handle non-JSON error response bodies in _error_body (#242)#274
thodson-usgs merged 3 commits into
DOI-USGS:mainfrom
SAY-5:fix/issue-242-error-body-non-json

Conversation

@SAY-5
Copy link
Copy Markdown
Contributor

@SAY-5 SAY-5 commented May 12, 2026

Closes #242.

_error_body blindly called resp.json() for any status other than 429 or 403. When the upstream API returned a non-JSON body (e.g. an openresty HTML 502), this raised requests.exceptions.JSONDecodeError, masking the real status code with a confusing JSON parse traceback.

The fix wraps the JSON parse in try/except ValueError (covers both json.JSONDecodeError and requests.exceptions.JSONDecodeError) and falls back to a status/reason message with a 200-char body snippet when the body isn't JSON. Empty bodies degrade to "<status>: <reason>.".

Tests added in tests/waterdata_utils_test.py:

  • HTML 502 body is summarized without raising
  • Empty body returns status + reason only
  • Long non-JSON bodies are truncated to 200 chars
  • Well-formed JSON error bodies still render code/description (no regression)

Local run: pytest tests/waterdata_utils_test.py -> 24 passed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves robustness of Waterdata OGC error handling by preventing _error_body from raising JSON decode exceptions when upstream services return non-JSON error bodies (e.g., HTML 5xx gateway pages), and adds regression tests for the new behavior.

Changes:

  • Wrap resp.json() in _error_body with try/except ValueError and fall back to a status/reason + truncated body snippet for non-JSON responses.
  • Add unit tests covering HTML/non-JSON bodies, empty bodies, truncation to 200 chars, and JSON-body non-regression.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
dataretrieval/waterdata/utils.py Makes _error_body resilient to non-JSON error bodies via a safe JSON-parse fallback path.
tests/waterdata_utils_test.py Adds tests for non-JSON/empty body handling, truncation behavior, and JSON regression coverage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread dataretrieval/waterdata/utils.py
Comment thread tests/waterdata_utils_test.py Outdated
thodson-usgs and others added 2 commits May 12, 2026 08:41
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
The existing docstring described behavior that never matched the code:
it said 429 returned a JSON `message` field (it returns a hardcoded
string) and that other statuses returned "raw response text" (they
return code/description from the JSON envelope, or a status/reason +
snippet for non-JSON bodies). Spell out the three branches
(429 hardcoded, 403 hardcoded, JSON-with-non-JSON-fallback) so the
docstring matches what the function actually returns.

Per Copilot review on PR DOI-USGS#274.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@thodson-usgs thodson-usgs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, thanks!

@thodson-usgs thodson-usgs merged commit 3550374 into DOI-USGS:main May 12, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

_error_body crashes with JSONDecodeError on non-JSON error responses (e.g. 502 from gateway)

3 participants