fix(webapp): a moment without Redis is a 503 to try again, not a 500 (#1326) #1327

Merged
claude-bot merged 2 commits from fix/1326-redis-503 into main 2026-11-03 19:28:42 +00:00
Collaborator

Closes #1326. Found by #1246's live checks.

  • The fault: a Redis restart under signed-in traffic turned requests into 500s for about a third of a second. The session read raised redis.exceptions.ConnectionError, which nothing caught.
  • The fix: a handler in app/main.py for Redis ConnectionError and TimeoutError answers 503 with Retry-After: 2 and {"detail": "Quest Board is briefly unavailable. Try again in a moment."}. It logs a warning, not a traceback. It is never a 401, so nobody is signed out of a session Redis still holds. It covers every Redis use, not only sessions.
  • The checklist: docs/OPERATIONS.md's worker-healthcheck step used kill, which isn't in the image, and docker pause, which Docker marks unhealthy without running the probe. It now stops and continues the process from the host with docker kill --signal=SIGSTOP/SIGCONT.

Checked on the dev host: the new test plus the auth and Redis-timeout tests, 50 passed. ruff format and check are clean, and the changelog check is OK.

The new sentence goes on the Wording Review page (part u) before merge.

🤖 Generated with Claude Code

Closes #1326. Found by #1246's live checks. - **The fault:** a Redis restart under signed-in traffic turned requests into 500s for about a third of a second. The session read raised `redis.exceptions.ConnectionError`, which nothing caught. - **The fix:** a handler in `app/main.py` for Redis `ConnectionError` and `TimeoutError` answers **503** with `Retry-After: 2` and `{"detail": "Quest Board is briefly unavailable. Try again in a moment."}`. It logs a warning, not a traceback. It is never a 401, so nobody is signed out of a session Redis still holds. It covers every Redis use, not only sessions. - **The checklist:** `docs/OPERATIONS.md`'s worker-healthcheck step used `kill`, which isn't in the image, and `docker pause`, which Docker marks unhealthy without running the probe. It now stops and continues the process from the host with `docker kill --signal=SIGSTOP/SIGCONT`. **Checked** on the dev host: the new test plus the auth and Redis-timeout tests, 50 passed. ruff format and check are clean, and the changelog check is OK. The new sentence goes on the Wording Review page (part u) before merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
A Redis restart under signed-in traffic gave 500s from the session
read for about a third of a second (#1246's live check). Connection and
timeout errors from Redis now answer 503 with Retry-After: 2 and the
usual {"detail": ...}; never a 401, which would sign people out.

OPERATIONS.md's worker-healthcheck step used a kill binary the image
doesn't have, and docker pause, which Docker marks unhealthy without
running the probe. It now uses docker kill --signal=SIGSTOP/SIGCONT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
style: wrap the 503 detail for ruff (#1326)
All checks were successful
CI / Does this change touch the recording path? (pull_request) Successful in 23s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Bot/backend version sync (pull_request) Successful in 50s
CI / Backend lint (ruff) (pull_request) Successful in 56s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 56s
CI / Which journeys does this change need? (pull_request) Successful in 33s
CI / Feedback site tests (pull_request) Successful in 1m31s
CI / Bot tests and audit (pull_request) Successful in 2m6s
CI / Docker image build (pull_request) Successful in 7m0s
CI / Frontend (shard 2/2) (pull_request) Successful in 9m8s
CI / Frontend (shard 1/2) (pull_request) Successful in 10m42s
CI / End-to-end journeys (desktop) (pull_request) Successful in 12m38s
CI / Backend migration, tests, and audit (pull_request) Successful in 36m54s
8cc212553a
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No description provided.