fix: auto-retry the startup error boundary on focus/online so a recovered backend un-sticks the app#3520
Conversation
…ered backend un-sticks the app Refs pingdotgg#3513 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This change adds new auto-retry behavior to the error boundary, triggering network requests on focus/visibility/online events. While the fix is straightforward and well-commented, it introduces runtime behavior changes that warrant human review. You can customize Macroscope's approvability policy. Learn more. |
Summary
The root route's
beforeLoadruns a startup auth/session probe; if it throws,RootRouteErrorViewis shown and persists until a manual reload (it does not re-run on focus). When that failure is transient (backend still starting, a flaky session call), the user is stranded on the error screen even after the backend recovers. This auto-retries the probe when the window regains focus/visibility or the network returns.Scope: this addresses the unrecoverable-overlay aspect of #3513. The underlying session-store write failure and the renderer-side diagnosability gap are tracked there separately — this PR intentionally stays small and single-concern.
Root cause
RootRouteErrorViewonly exposesreset()(resets the error boundary) andwindow.location.reload().reset()does not re-runbeforeLoad, so a transient startup-probe failure leaves a sticky dead-end until a manual reload.router.invalidate()re-runs matched routes'beforeLoad/loaders and resets the boundary.What changed
In
RootRouteErrorView, onvisibilitychange→visible, windowfocus, oronline, callrouter.invalidate()— guarded by an in-flight ref so noisy (Electron) focus events don't stack concurrent retries. The retry is intentionally broad (it fires for any boundary error) and harmless: it's focus/online-gated and ref-locked, so a persistent failure just re-shows the error rather than looping. No behavior change on the success path.Validation
vp run --filter @t3tools/web typecheck— cleanvp lint— 0 errorsvp run --filter @t3tools/web test— 1155/1155 passI didn't add a unit test: the web suite has no DOM-render harness (no jsdom/testing-library — components are tested by structural invocation), so a
window-event effect test doesn't fit the current setup. Happy to add one if you point me at the preferred pattern for DOM/router-effect tests.Refs #3513
Note
Low Risk
Small, error-boundary-only UX change with ref-gated retries; no changes to auth logic or the happy path.
Overview
When the root route’s
beforeLoadstartup probe fails,RootRouteErrorViewused to stick until a full reload—reset()does not re-runbeforeLoad, so a transient backend or session failure could strand users even after recovery.RootRouteErrorViewnow auto-retries by callingrouter.invalidate()when the tab becomes visible, the window gains focus, or the browser goes online. An in-flight ref prevents stacked retries from noisy focus events (e.g. Electron). Persistent failures still show the same error screen; the success path is unchanged.Manual Try again / Reload app buttons are unchanged.
Reviewed by Cursor Bugbot for commit c4b0b8b. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Auto-retry the startup error boundary on focus, visibility, and network recovery
When the root error boundary is shown, the app was stuck until a manual reload even if the backend recovered. The
RootRouteErrorViewcomponent in __root.tsx now registers listeners forvisibilitychange,focus, andonlineevents and callsrouter.invalidate()on each, re-runningbeforeLoadand exiting the error boundary automatically if the backend is healthy. AretryingRefguard prevents concurrent retry attempts.Macroscope summarized c4b0b8b.