SvelteKit error handling
The @flareapp/sveltekit package provides error hooks that integrate with SvelteKit's handleError hook in both hooks.client.ts and hooks.server.ts. These hooks catch unhandled errors and report them to Flare with SvelteKit-specific context including the current route, URL, params, and query parameters.
Note: Server-side error handling is currently experimental. Flare does not yet have access to server-side source files, so server error reports will have limited stack trace resolution.
Client-side error handling
Set up the error hook in src/hooks.client.ts:
// src/hooks.client.ts
import { flare } from '@flareapp/js';
import { handleErrorWithFlare } from '@flareapp/sveltekit/client';
flare.light('YOUR PROJECT KEY');
export const handleError = handleErrorWithFlare();
The client-side hook automatically:
- Skips 4xx errors (expected client-side responses),
- Unwraps SvelteKit error objects,
- Builds route context from
$app/state(current URL, route ID, params, redacted query params), - Reports the error to Flare,
- Starts route context tracking so every subsequent error includes the current route.
Server-side error handling (experimental)
Set up the error hook in src/hooks.server.ts:
// src/hooks.server.ts
import { flare } from '@flareapp/js';
import { handleErrorWithFlare } from '@flareapp/sveltekit/server';
flare.light('YOUR PROJECT KEY');
export const handleError = handleErrorWithFlare();
The server-side hook works the same way as the client-side hook, except it extracts route context from the SvelteKit RequestEvent object instead of $app/state.
SvelteKit context
Each error report includes SvelteKit-specific context under the svelte.svelteKit key:
{
"context": {
"svelte": {
"componentName": null,
"componentHierarchy": [],
"errorOrigin": "unknown",
"svelteKit": {
"routeId": "/users/[id]",
"url": "/users/42",
"params": { "id": "42" },
"query": { "tab": "settings" },
"status": 500,
"message": "Internal Error"
}
}
}
}
routeId- The SvelteKit route pattern (e.g./users/[id]), ornullif unknown.url- The pathname without the origin.params- Route parameters extracted from the URL.query- Query parameters, with sensitive keys redacted (password, token, secret, authorization, cookie, api_key, session, csrf, etc.).status- The HTTP status code (e.g.500).message- The error message from SvelteKit's error handler.
Lifecycle hooks
handleErrorWithFlare() accepts an options object with three lifecycle hooks. All callbacks receive { error, status, message } and, for beforeSubmit/afterSubmit, a context object:
// src/hooks.client.ts
import { flare } from '@flareapp/js';
import { handleErrorWithFlare } from '@flareapp/sveltekit/client';
flare.light('YOUR PROJECT KEY');
export const handleError = handleErrorWithFlare({
beforeEvaluate: ({ error, status, message }) => {
flare.addContext('user', { id: currentUser.id });
},
beforeSubmit: ({ error, status, message, context }) => {
return {
...context,
svelte: {
...context.svelte,
customField: 'value',
},
};
},
afterSubmit: ({ error, status, message, context }) => {
console.error('Error reported to Flare:', error.message);
},
});
The three hooks fire in this order:
beforeEvaluate- called after the error is caught, before building the route context. Use this to attach custom context to Flare (e.g. user info, feature flags).beforeSubmit- called with the built context, must return a (possibly modified) context object. Use this to filter or enrich the report context before it is sent.flare.report()- the error is reported to Flare.afterSubmit- called after the report is initiated. The report is sent asynchronously, so this callback runs before the network request completes.
These hooks are separate from flare.configure({ beforeEvaluate, beforeSubmit }). The handler hooks add context and run side effects but cannot suppress errors. To filter errors, use the client-level hooks:
flare.configure({
beforeEvaluate: (error) => {
if (error.message.includes('Boring error')) {
return false; // Don't report this error
}
return error;
},
});
See the client hooks documentation for more details.
Chaining with existing error handlers
You can pass an existing handleError function directly to handleErrorWithFlare(), and it will be called after the error is reported to Flare:
// src/hooks.client.ts
import { flare } from '@flareapp/js';
import { handleErrorWithFlare } from '@flareapp/sveltekit/client';
flare.light('YOUR PROJECT KEY');
const myErrorHandler = ({ error, status, message }) => {
console.error('Custom handler:', error);
};
export const handleError = handleErrorWithFlare(myErrorHandler);
4xx error skipping
handleErrorWithFlare() automatically skips errors with 4xx status codes (400–499), since these represent expected client-side responses like 404 Not Found or 403 Forbidden — not application errors.
If you need to capture specific 4xx errors, use captureError() instead, which does not skip any status codes.
Capturing errors manually
The captureError() function lets you manually report errors to Flare with SvelteKit route context. Unlike handleErrorWithFlare(), it does not skip 4xx errors — you control which errors to report.
This is useful for errors you catch yourself in load functions, form actions, API routes, or event handlers that you want to report to Flare without re-throwing.
Client-side usage
On the client, captureError() automatically picks up route context from $app/state:
import { captureError } from '@flareapp/sveltekit/client';
try {
await riskyOperation();
} catch (error) {
captureError(error);
}
You can optionally pass status and message for additional context:
captureError(error, {
status: 503,
message: 'Service temporarily unavailable',
});
Server-side usage (experimental)
On the server, pass the RequestEvent as the event option so captureError() can extract route context:
// src/routes/api/checkout/+server.ts
import { captureError } from '@flareapp/sveltekit/server';
export async function POST(event) {
try {
await processPayment(event);
} catch (error) {
captureError(error, { event });
return new Response('Payment failed', { status: 500 });
}
}
In load functions and form actions:
// src/routes/dashboard/+page.server.ts
import { captureError } from '@flareapp/sveltekit/server';
export async function load(event) {
try {
return { data: await fetchDashboardData() };
} catch (error) {
captureError(error, {
event,
status: 500,
message: 'Failed to load dashboard data',
});
return { data: null };
}
}
Differences from handleErrorWithFlare()
handleErrorWithFlare() |
captureError() |
|
|---|---|---|
| Usage | SvelteKit handleError hook |
Manual, anywhere in your code |
| Skips 4xx errors | Yes | No |
| Route context (client) | From $app/state |
From $app/state |
| Route context (server) | From SvelteKit's hook parameter | From options.event |
| Lifecycle hooks | beforeEvaluate, beforeSubmit, afterSubmit |
None (use flare.configure() for filtering) |
Options reference
handleErrorWithFlare() options
| Option | Type | Description |
|---|---|---|
beforeEvaluate |
({ error, status, message }) => void |
Called before route context is built. |
beforeSubmit |
({ error, status, message, context }) => FlareSvelteKitContext |
Called before submitting; must return a (possibly modified) context. |
afterSubmit |
({ error, status, message, context }) => void |
Called after flare.report() is called (the report is sent asynchronously). |
captureError() options
| Option | Type | Description |
|---|---|---|
event |
RequestEvent (server only) |
The SvelteKit request event, used to extract route context. Ignored on the client. |
status |
number |
Optional HTTP status code to attach to the report. |
message |
string |
Optional message to attach to the report. |