Skip to content

fix(dashboard): wrap each screen in its own ErrorBoundary - #623

Open
16navigabraham wants to merge 1 commit into
Sorokit:mainfrom
16navigabraham:fix/per-screen-error-boundaries
Open

fix(dashboard): wrap each screen in its own ErrorBoundary#623
16navigabraham wants to merge 1 commit into
Sorokit:mainfrom
16navigabraham:fix/per-screen-error-boundaries

Conversation

@16navigabraham

Copy link
Copy Markdown

Summary

Closes #564. Each screen rendered by Dashboard now has its own ErrorBoundary, so a crash in one screen no longer takes down the Sidebar, TopBar, or any other (hidden) screen.

Problem

Dashboard.tsx had no ErrorBoundary of its own — the only one in the app lived in main.tsx, wrapping the entire <App />. A render error thrown by any single screen (e.g. TransactionsScreenTransactionHistory) propagated all the way up and replaced the whole shell with the generic full-page fallback, discarding the sidebar, the active wallet/network context UI, and any state in the other screens that Dashboard normally keeps mounted-but-hidden.

What changed

  • src/screens/Dashboard.tsx
    • Each screen in the visited map is now wrapped in its own <ErrorBoundary isolate>, scoped to that screen's <div data-testid="screen-wrapper-..."> — Sidebar, TopBar, and NetworkBanner render outside this boundary and are unaffected by a crash inside it.
    • Added a small ScreenErrorFallback component (screen name + a "Retry" button) passed in as the boundary's fallback prop, so the fallback names the screen instead of showing ErrorBoundary's generic "Something went wrong" copy.
    • SCREEN_LABELS maps each NavSection to its display name for the fallback (mirrors the existing PAGE_TITLES map).
    • No changes to ErrorBoundary.tsx itself or to the root boundary in main.tsxErrorBoundary's existing reset()/resetKey mechanism already remounts only its own children, which is exactly what "Retry re-mounts only the affected screen" needs.
  • src/screens/Dashboard.test.tsx — new describe("per-screen error boundaries (#564)") block (4 tests): a crashing screen doesn't take down the Sidebar/TopBar, the fallback shows the screen name and a Retry button, Retry recovers and re-mounts just that screen, and navigating to a different (working) screen is unaffected while the crashed one shows its fallback.

Acceptance criteria

  • Each screen rendered in Dashboard.tsx is wrapped in its own ErrorBoundary
  • A crash in TransactionHistory does not bring down the Sidebar or TopBar
  • The per-screen fallback shows the screen name and a Retry button
  • Retry clears the boundary and re-mounts only the affected screen
  • The root ErrorBoundary in main.tsx is kept as a last-resort catch-all

Testing

  • npx vitest run src/screens/Dashboard.test.tsx → 15/15 pass (11 existing + 4 new).
  • npm run typecheck → clean.
  • npm run build → succeeds.

Note for maintainers

While verifying this change I found this repo's main already has some pre-existing, unrelated breakage independent of this PR: npm run lint currently fails on BatchPaymentProcessor.tsx, ClaimableBalanceCard.tsx, and SorokitProvider.tsx (react-hooks rule violations) and on src/lib/utils.test.ts; npm run test:exports and the production npm run build's inline typecheck both fail on a string | null vs string mismatch in TransactionPanel.tsx:204; and npm run size fails to resolve dist imports. I confirmed all of these reproduce identically on a clean checkout of main via git stash, so none of it is introduced by this PR — flagging in case it's useful, but intentionally out of scope here.

A crash in one screen (e.g. TransactionHistory) previously tore down
the entire Dashboard, including the Sidebar and TopBar, because only
a single root-level ErrorBoundary existed in main.tsx.

Each screen rendered by Dashboard now gets its own isolate-mode
ErrorBoundary with a scoped fallback that names the crashed screen
and offers a Retry button, which clears the boundary and re-mounts
only that screen. The root ErrorBoundary in main.tsx is unchanged and
still catches anything above Dashboard as a last resort.

Closes Sorokit#564
Copilot AI lite review requested due to automatic review settings August 29, 2026 11:15
@drips-wave

drips-wave Bot commented Aug 29, 2026

Copy link
Copy Markdown

@16navigabraham Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

Only one root ErrorBoundary exists — a crash in any screen tears down the entire Dashboard

2 participants