Skip to content

panel: retry transient failures + maintenance overlay (survive roll cutovers) - #23

Merged
pipozzz merged 1 commit into
mainfrom
feat/panel-retry-maintenance
Oct 6, 2026
Merged

pipozzz merged 1 commit into
mainfrom
feat/panel-retry-maintenance

Conversation

@pipozzz

@pipozzz pipozzz commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Why

When the panel self-updates (a Nomad canary roll), Traefik returns 502/503/504 during the cutover (no healthy backend). The tRPC/React-Query client had no retry config, so any action submitted in that window (Redeploy, a var-file save) failed silently and a failed request read as a logout — the root cause behind "the panel loses my actions" / spurious logouts.

Sessions themselves are fine (DB-backed, stable BETTER_AUTH_SECRET) — this is purely request resilience during the cutover.

What

  • Transient-only retry (utils/api.ts): isTransientError() + queryClientConfig retry — queries 5×, mutations 3×, only on 5xx/network errors (never 4xx), exponential backoff capped at 5s. An action during a cutover now retries and succeeds once the panel is back, instead of being lost. (In @trpc/next v11, queryClientConfig belongs inside the config() return — verified type-correct there.)
  • Maintenance overlay (components/shared/maintenance-overlay.tsx, mounted in _app.tsx): a slim, non-blocking "Panel is updating — reconnecting…" banner that polls /api/health (15s healthy / 2s down) and auto-clears when the panel answers. Never a full-screen trap.

Notes

This mitigates the user-facing impact of the panel-roll cutover (actions survive it) independently of solving the cutover 502s themselves (that remains a separate offline investigation).

Validation

scripts/check.sh green (server build, 529 tests, app-tsc unchanged / 8 pre-existing). Biome clean.

🤖 Generated with Claude Code

…utovers)

When the panel self-updates (Nomad canary roll), Traefik returns 502/503/504
for the cutover window and in-flight requests can fail at the network layer. The
tRPC client had no retry config, so actions submitted then (e.g. Redeploy, a
save) failed silently and a failed request read as a logout.

- api.ts: isTransientError() + queryClientConfig retry — queries 5x, mutations
  3x, ONLY on 5xx/network errors (never 4xx), exponential backoff capped at 5s.
  So an action during a cutover retries and succeeds once the panel is back.
  (In @trpc/next v11 queryClientConfig goes inside the config() return.)
- maintenance-overlay.tsx + _app.tsx: a slim non-blocking 'Panel is updating —
  reconnecting…' banner that polls /api/health (15s healthy / 2s down) and
  auto-clears when the panel answers. Never traps the user.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pipozzz
pipozzz merged commit 767047f into main Oct 6, 2026
2 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.

1 participant