Skip to content

Don't cache error responses, and return accurate error codes from Arctic hydrology endpoints - #738

Merged
cstephen merged 1 commit into
mainfrom
dont-cache-errors
Aug 3, 2026
Merged

Don't cache error responses, and return accurate error codes from Arctic hydrology endpoints#738
cstephen merged 1 commit into
mainfrom
dont-cache-errors

Conversation

@brucecrevensten

Copy link
Copy Markdown
Member

Note

This PR was AI-generated (Claude Code) and human-reviewed before submission.

Summary

Two related fixes around error handling:

  • Error responses are no longer cached for 90 days. The after_request hook set Cache-Control: max-age=7776000 on every response, including errors. A transient upstream hiccup could therefore be served from cache for months after the upstream recovered. Now only 200 responses get the 90-day max-age; everything else gets a 60-second max-age — short enough to recover quickly, long enough to shield upstreams from request storms during a real outage.
  • Arctic hydrology endpoints return accurate error codes. get_features() in routes/arctic_hydrology.py returned 400 Bad Request for every failure, whether the WFS fetch to GeoServer failed or the stream ID simply had no features. It now returns 502 Upstream Data Unreachable for fetch failures and 404 No Data for unknown stream IDs (both using existing templates). The two isinstance(gdf, tuple) early-return comments in the stats and modeled-climatology routes are updated to match.

Manual testing

  1. Run the API locally:
    micromamba activate api-env
    export FLASK_APP=application.py
    export FLASK_DEBUG=True
    flask run
    
  2. 200 + long cache: curl -sI http://localhost:5000/arctic_hydrology/stats/81000004 — expect 200 and Cache-Control: max-age=7776000.
  3. 404 + short cache: curl -sI http://localhost:5000/arctic_hydrology/stats/1 (a stream ID with no features) — expect 404 and Cache-Control: max-age=60, and the "No data" page in a browser.
  4. 502 + short cache: restart Flask with GeoServer pointed somewhere unreachable, e.g. export API_GS_BASE_URL=http://localhost:9999/, then repeat the request from step 2 — expect 502 and Cache-Control: max-age=60, and the "Upstream Data Unreachable" page in a browser. Unset API_GS_BASE_URL afterwards.
  5. Spot-check that an unrelated non-hydrology endpoint still returns Cache-Control: max-age=7776000 on success.

🤖 Generated with Claude Code

…tic hydrology endpoints

Error responses were cached with the same 90-day max-age as successful
responses, so a transient upstream failure could be served from cache
long after the upstream recovered. Errors now get a 60-second max-age
instead; 200s keep the 90-day TTL.

Also, get_features() in the Arctic hydrology routes returned 400 Bad
Request for every failure. It now distinguishes a WFS/upstream fetch
failure (502) from a stream ID with no features (404).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@brucecrevensten
brucecrevensten requested a review from cstephen July 31, 2026 20:06

@cstephen cstephen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This all looks good to me. The code diff makes sense, and I've confirmed that the Cache-Control: max-age=is set to to the appropriate length of time for HTTP 200 vs. 404 or 502 status codes. (The Data API won't start with a bad GeoServer URL domain, so I had to test the HTTP 502 status codes by running against the production GeoServer URL, but temporarily changed the generate_wfs_arctic_hydrology_url function to return bogus URLs.)

@cstephen
cstephen merged commit 1f6fcf8 into main Aug 3, 2026
1 check failed
@cstephen
cstephen deleted the dont-cache-errors branch August 3, 2026 22:16
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.

2 participants