Skip to content

utils.query: surface unhandled 4xx/5xx and stop mutating caller's payload#253

Draft
thodson-usgs wants to merge 1 commit intoDOI-USGS:mainfrom
thodson-usgs:fix/utils-query-error-handling
Draft

utils.query: surface unhandled 4xx/5xx and stop mutating caller's payload#253
thodson-usgs wants to merge 1 commit intoDOI-USGS:mainfrom
thodson-usgs:fix/utils-query-error-handling

Conversation

@thodson-usgs
Copy link
Copy Markdown
Collaborator

Summary

Two related correctness fixes to the shared HTTP wrapper used by every module in the package.

  • Unhandled 4xx/5xx silently passed through. `query` only formatted explicit messages for 400, 404, 414, and 500/502/503 — every other status (401, 403, 405, 408, 429, 501, 504, …) fell through and the response was returned as if it had succeeded. Callers then parsed an HTML error page as RDB or CSV and reported confusing downstream errors. Adds a `response.raise_for_status()` call after the explicit branches so every non-success surfaces, while keeping the friendlier messages for the codes we already format.

  • `query` mutated the caller's payload dict. The body did `for key, value in payload.items(): payload[key] = to_str(...)` in place, so list values came back replaced with their stringified joins after the call returned. Build a fresh `params` dict in a comprehension and leave the input alone.

Test plan

  • New parametrized test covers seven previously-silent statuses (401, 403, 405, 408, 429, 501, 504) — each now raises.
  • New test verifies the caller's payload dict is not mutated and list values still point at the same object.
  • Existing `test_url_too_long` and `test_header` continue to pass.
  • Full local test suite passes (234 tests, with `API_USGS_PAT` set).

… payload

Two related correctness fixes to the shared HTTP wrapper used by every
module in the package.

* The function only formatted explicit messages for 400, 404, 414, and
  500/502/503. Any other status (401, 403, 405, 408, 429, 501, 504, …)
  fell through and the response was returned as if it had succeeded —
  callers parsed an HTML error page as RDB or CSV. Add a
  ``raise_for_status()`` after the explicit branches so every
  non-success surfaces, while keeping the friendlier messages for the
  codes we already format.

* The body did
  ``for key, value in payload.items(): payload[key] = to_str(...)``,
  mutating the caller's dict. List values came back replaced with their
  stringified joins, breaking any caller that re-used the dict. Build a
  fresh ``params`` dict in a comprehension and leave the input alone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant