patternjavascriptsvelteMajor
SvelteKit error handling: expected vs unexpected errors
Viewed 0 times
SvelteKit 1.x+
sveltekit errorerror()+error.sveltehandleError404expected error
Error Messages
Problem
Unhandled errors in SvelteKit load functions crash pages without useful feedback. Expected errors (404, 401) and unexpected errors require different handling strategies.
Solution
Use error() for expected errors, let unexpected errors propagate to handleError:
// +page.server.ts
import { error } from '@sveltejs/kit';
export async function load({ params }) {
// Expected error — user sees +error.svelte
const post = await db.post.findUnique({ where: { id: params.id } });
if (!post) throw error(404, { message: 'Post not found' });
// Unexpected error — don't throw error(), just let it throw
// It goes to handleError in hooks.server.ts
const related = await db.post.findMany(); // if this throws, it's unexpected
return { post, related };
}
<!-- src/routes/+error.svelte -->
<script>
import { page } from '$app/stores';
</script>
<h1>{$page.status}</h1>
<p>{$page.error?.message}</p>
<!-- Layout-level error boundary -->
<!-- Create +error.svelte next to +layout.svelte to catch errors for that layout -->
// hooks.server.ts
export const handleError: HandleServerError = ({ error, event }) => {
console.error('Unexpected error:', error);
// Return safe user-facing message
return { message: 'Something went wrong', errorId: crypto.randomUUID() };
};
// +page.server.ts
import { error } from '@sveltejs/kit';
export async function load({ params }) {
// Expected error — user sees +error.svelte
const post = await db.post.findUnique({ where: { id: params.id } });
if (!post) throw error(404, { message: 'Post not found' });
// Unexpected error — don't throw error(), just let it throw
// It goes to handleError in hooks.server.ts
const related = await db.post.findMany(); // if this throws, it's unexpected
return { post, related };
}
<!-- src/routes/+error.svelte -->
<script>
import { page } from '$app/stores';
</script>
<h1>{$page.status}</h1>
<p>{$page.error?.message}</p>
<!-- Layout-level error boundary -->
<!-- Create +error.svelte next to +layout.svelte to catch errors for that layout -->
// hooks.server.ts
export const handleError: HandleServerError = ({ error, event }) => {
console.error('Unexpected error:', error);
// Return safe user-facing message
return { message: 'Something went wrong', errorId: crypto.randomUUID() };
};
Why
error() throws a special HttpError that SvelteKit catches and renders the nearest +error.svelte with the status code. Unexpected errors (unhandled exceptions) go through handleError for logging, and the user sees a generic 500 error page.
Gotchas
- +error.svelte must be colocated with the +layout.svelte it belongs to
- error() inside a load function is caught by the parent layout's +error.svelte
- redirect() is similar — it throws and must not be caught in a try/catch
- Client-side errors in components are not caught by +error.svelte — use onError event
Code Snippets
Re-throwing SvelteKit special errors inside try/catch
// Don't catch redirect or error throws
try {
const data = await loadData();
if (!data) throw error(404); // NOT caught by try/catch below
} catch (e) {
// This also catches redirect/error — re-throw them!
if (e instanceof HttpError || e instanceof Redirect) throw e;
console.error(e);
}Context
When handling errors in SvelteKit load functions and server actions
Revisions (0)
No revisions yet.