Overview
GlobalErrorHandler wraps your app and catches all unhandled errors
(window.error and unhandledrejection). On catch it runs your
chosen recovery strategy and optionally renders a full-page error UI. SessionStorage-based
loop prevention stops the strategy from running away.
showToast config field is gone. Notification UI is now your
responsibility — wire your favorite toast library inside the onError callback.
See below for the migration recipe./error-handling-demo →Quick Start
1. Configure in main.js
2. Wrap your app with GlobalErrorHandler
GlobalErrorHandler is a wrapper — pass your app content as
children, not as a sibling.
Recovery strategies
navigateSafe — navigate to a known-good route (default)
Pushes safeRoute when an error fires. Best for most apps with a reliable landing page.
restart — full app reload
Hard-refreshes the page. Useful when errors are likely due to corrupted in-memory state.
The autoRestart + restartDelay options control whether the reload
is automatic or user-triggered.
showError — full-page error UI
Renders the error component (built-in ErrorDisplay by default, or your own via
the errorComponent snippet prop on GlobalErrorHandler). The user
picks their own recovery path.
custom — run your own recovery
The router catches the error, then hands it to your onRecover callback with
helpers for restart / navigate / show-error so you can decide what to do.
⚠️ showToast removed in v5.2.0
Previously the library rendered a built-in <div class="error-toast"> on
caught errors, gated by showToast (default true). The render
guard was broken under the default navigateSafe strategy: it called clearError() synchronously after push() in the same handler tick,
so by the time Svelte's reactive system flushed toastVisible = true, the
error state was already gone and the toast never rendered.
Rather than patch the broken interaction, the toast was removed. Every app already has a preferred toast/snackbar library — the router's job is to surface the event, not paint pixels.
TypeScript will flag the now-unknown property, so a typecheck after upgrade is the easiest way to find every call site that needs updating.
Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
strategy | 'navigateSafe' | 'restart' | 'showError' | 'custom' | 'navigateSafe' | Recovery behavior on caught error |
safeRoute | string | '/' | Used by navigateSafe strategy |
maxRestarts | number | 3 | Max restarts allowed within restartWindow |
restartWindow | number (ms) | 60000 | Sliding window for counting restarts |
autoRestart | boolean | false | When strategy: 'restart', restart automatically vs wait for user |
restartDelay | number (ms) | 5000 | Delay before auto-restart fires |
showErrorComponent | boolean | false | Render the full-page error UI when an error is active |
onError | (error, errorInfo, context) => void | — | Logging / monitoring hook. Fires on every catch, independent of strategy. This is where your toast library goes. |
onRecover | (error, errorInfo, context, helpers) => void | — | Recovery callback. Only fires when strategy: 'custom'. |
ignoreErrors | (RegExp | string)[] | [] | Errors matching any pattern are silently dropped (no onError, no recovery) |
isDevelopment | boolean | false | Default ErrorDisplay shows stack traces only when true |
Filtering noisy errors with ignoreErrors
Pass an array of patterns. Matching errors never reach onError or the
recovery strategy — they're treated as if they hadn't been thrown.
Restart loop prevention
When an error keeps firing during recovery (e.g. a broken initialization that breaks safeRoute too), the restart counter prevents infinite loops. Counts live
in sessionStorage under __svelte_spa_router_restart_count and
expire after restartWindow.
The counter resets when:
- The user navigates without an error
- The browser tab is closed (sessionStorage scope)
- The window passes without new restarts
Helper functions
All exported from @keenmate/svelte-spa-router/helpers/error-handler. Inside onRecover, the same helpers are passed as the helpers argument.
restart()
Trigger a restart, respecting maxRestarts. Returns true if it actually restarted, false if rate-limited.
navigate(route)
Navigate to any route. Takes a path string argument (unlike safeRoute, which is configured once).
showError()
Force the full-page error UI to render (assumes showErrorComponent: true is configured).
canRestart() / getRestartCount()
Inspect the restart state — useful for gating a "Try again" button in your custom error component.
Custom error UI via errorComponent snippet
Pass an errorComponent snippet to GlobalErrorHandler. The snippet
receives an ErrorComponentProps argument with the error, the error info, and
recovery callbacks bound to the configured strategy.
Snippet props (ErrorComponentProps): error, errorInfo, onRestart, onNavigateSafe, onContinue, canRestart.
Integration with error tracking
Sentry
Analytics + toast
Best practices
Pick the right strategy
navigateSafe— most apps with a reliable home pagerestart— stale-state issues that a reload would fixshowError— dev mode, or when you want users to choose recoverycustom— branching recovery logic (e.g. different routes per error type)
Don't conflate logging and recovery
onError is for monitoring / toasts / analytics — fires on every catch
regardless of strategy. onRecover is only for the custom strategy
and decides what happens. Keep them separate.
Always wrap with GlobalErrorHandler
If your app content isn't inside <GlobalErrorHandler>, errors won't be
caught. Wrapping at the root means it covers every route.
Filter known-noisy errors
ResizeObserver loop and AbortError are textbook examples — neither
is a real bug, both will trigger recovery if you don't ignore them.
Troubleshooting
Errors aren't being caught
- Verify your app content is inside
<GlobalErrorHandler>(not a sibling) - Check
ignoreErrors— is the pattern accidentally matching the error you care about? - Confirm
configureGlobalErrorHandlerran beforemount(App, …)
onRecover never fires
Restart loop never stops
- Lower
maxRestarts(e.g.2) - Clear sessionStorage manually during debugging:
delete sessionStorage.__svelte_spa_router_restart_count - If the error fires on every route (including
safeRoute),navigateSafecan't recover — switch toshowErrorso the user can act