You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(errors): unify HTTP status->exception across all request paths
Adds a single classifier so every HTTP error response raises the correct typed
DataRetrievalError, replacing four divergent paths (legacy query handled only
400/404/414/5xx; waterdata mapped other 4xx to a bare RuntimeError; nldi raised
a bare ValueError; nadp/streamstats raised httpx.HTTPStatusError).
- exceptions.py: add `error_for_status(status, message, *, retry_after)` -- the
one status->type map (400->BadRequestError, 404->NotFoundError,
413/414->URLTooLong, 429->RateLimited, 5xx->ServiceUnavailable, other
4xx->new ClientError) -- plus `ClientError(DataRetrievalError, ValueError)`.
- Route every path through it: utils._raise_for_status (legacy query, now also
429 + generic 4xx), waterdata._raise_for_non_200 (drops the bare RuntimeError),
nldi._query_nldi, and nadp/streamstats (were raise_for_status()).
- A given status now surfaces as the same type everywhere, and a 429 is a
RateLimited rather than a fatal ValueError on the single-shot paths too.
The type classifies the HTTP *condition* only -- it does NOT imply the path
retries it. Auto-retry/resume remains a Water Data chunker feature; the
single-shot query/nadp/streamstats paths raise the typed error without retrying
(a caller can read retry_after and re-issue). Connection-level failures
(timeouts/DNS) still surface as httpx errors on those paths. The general
exceptions module documents none of the chunker's resume internals -- that stays
in waterdata/chunking (the correct dependency direction).
mypy --strict clean; ruff clean; suite green (nwis live-test network flakes are
environmental, pass in isolation).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments