feat(status): app-wide server-unreachable banner with recovery poll (MAPPS-333) #383
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/MAPPS-333-server-unreachable-banner"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
When mokosh-server is unreachable the app surfaced a scatter of cryptic per-page toasts, empty pages, or CORS-looking console errors, with no single clear signal that the backend was down. This reflects it as one app-wide state instead, and clears it automatically on recovery. Closes MAPPS-333.
Changes
SERVER_REACHABLEGlobalSignal (default reachable) inhooks::fetch, classified by the central request helpers: a transport/connection failure, timeout, or5xxflips it to down; any real response (incl.4xx) clears it. The opaque "Failed to fetch" / CORS-looking rejection is classified here as server-unreachable and is never shown to the user as a CORS message.4xx(auth, validation) is not "down" and keeps surfacing through the normal per-call paths.ServerStatusBannermounted atAppLayout: a single non-blocking "Server unreachable. Reconnecting..." bar while down, with a bold + underlined "Click to see more..." link to the System Status page (per the in-thread request). Pages stay visible; existing per-page toasts are unchanged. Renders nothing while healthy (zero-height, and keeps the link out of the tab order until actionable).use_server_status_monitorat the App root: polls/readyevery 10s only while down and stops on first success (the probe's own classification flips the flag back), so there is no added traffic while healthy and the banner auto-dismisses on recovery with no user action. Implemented as ause_resourcesubscribed to the flag: idle while reachable, looping while down.Notes
Signal) for the same reasonTENANT_GENERATIONis one: theapihelpers are plain async fns, not components, and must flip the flag from outside the reactive tree. WASM is single-threaded, so a GlobalSignal is the right primitive (same rationale as the toast surface).Verification
All green in the
rust-builder-glibc:v1.0.1-rust1.94-trixieCI container (and the pre-commit hook):cargo fmt --all --check,cargo clippy --all-targets -- -D warnings,cargo check --target wasm32-unknown-unknown,cargo test --lib(189 tests).Manual verification (live stack, not exercisable here): stopping mokosh-server shows the banner within one poll interval with a console free of unexplained CORS errors; restarting it clears the banner automatically.