fix(frontend): stop false Server Unreachable alerts while the tab is hidden#113
Merged
Merged
Conversation
…reachable alerts while the tab is hidden
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
During a live meeting, the app raised two "Server Unreachable: Cannot connect to Nojoin Backend API." error toasts even though the backend was healthy the whole time and the recording completed with zero data loss.
Root cause is entirely client-side. The backend health poller in
serviceStatusStore.tsruns on asetTimeoutloop independent of tab visibility. When the Nojoin tab is backgrounded (as it is during a call the user is watching in another window), the browser throttles its timers and deprioritises its network requests, so the health probe's 5sAbortControllertimes out even while the backend is fine. Three consecutive timeouts (backendFailCount > 2) trip the persistent "Server Unreachable" alert inServiceStatusAlerts.tsx. Meanwhile the high-priority MediaRecorder segment uploads kept succeeding without a single sequence gap, so the poller was declaring the backend unreachable at the exact moments it was demonstrably reachable.Log evidence from the incident:
nojoin-apireturned 200 across both windows,nojoin-nginxlogged no errors/timeouts, segment sequences were gap-free for the affected recording, and the recording finalized 200 OK.Fix: skip the probe (without accruing failures) when
document.visibilityState === "hidden", guarded bytypeof document !== "undefined"for SSR safety. The existing focus/visibilitychangehandler inServiceStatusAlerts.tsxalready forces an immediate re-check on return to the foreground, so a genuine outage is still surfaced the moment the user looks at the tab.No new dependencies.
Fixes # (n/a — reported from production logs)
Type of change
Checks run
source .venv/bin/activate && pytest(not run locally; frontend-only change, covered by CI "Backend tests")python scripts/check.py(not run; no Python touched)cd frontend && npm run lintcd frontend && npm run test(37 files, 182 tests passed)cd frontend && npm run buildpython3 scripts/validate_docs.pypython3 scripts/validate_alembic.pyMigration impact
Documentation impact
Security impact
Manual verification
Added a unit test asserting
checkBackend()does not fetch and does not incrementbackendFailCountwhiledocument.visibilityStateis "hidden", and that previously-known-good status is preserved. Existing tests (which run under jsdom's default "visible" state) are unchanged and still pass.Recommended manual smoke before merge: start a recording, switch to another window/tab for a couple of minutes so the Nojoin tab is backgrounded, confirm no "Server Unreachable" toast appears, return to the tab and confirm status stays healthy; separately, stop the backend while the tab is foregrounded and confirm the alert still fires as before.