SSR framework for Svelte 5 + Bun with islands-based selective hydration
Error handling
Mochi renders an error page for uncaught page-render errors, error(status, ...) thrown from serverProps or actions, and any request that doesn’t match a route. API routes are unaffected — they return a JSON envelope instead; see API routes → Error responses above.
Configure an error page via errorPage on Mochi.serve(). If omitted, a minimal built-in component is used.
await Mochi.serve({
errorPage: './src/Error.svelte',
handleError: ({ error, status, event }) => {
if (status >= 500) console.error('[app]', event.url.pathname, error);
},
routes,
});The error component receives a single error prop:
<script lang="ts">
import type { MochiErrorProps } from 'mochi-framework';
let { error }: MochiErrorProps = $props();
</script>
<h1>{error.status}</h1>
<p>{error.message}</p>
{#if error.stack}<pre>{error.stack}</pre>{/if}| Field | Description |
|---|---|
status | HTTP status — 404, 500, or whatever was passed to error() |
message | Human-readable message — safe to render |
stack | Stack trace. Only populated when development: true, else absent |
handleError hook
Fires whenever the error page is about to render — uncaught page/form render errors, unmatched routes, unknown form actions, and malformed form bodies. Use it to log, forward to error tracking, or sanitize the message the user sees.
error is null when the condition didn’t originate from a throw (e.g. unmatched routes, unknown form actions). Inspect it before forwarding so benign 4xx cases don’t page on-call.
Return one of:
{ status, message }— override either field passed to the error component- a
Response— short-circuit rendering entirely (useful for redirects or custom responses) - nothing — keep the defaults
import type { HandleError } from 'mochi-framework';
const handleError: HandleError = ({ error, event, status, message }) => {
if (error) tracker.capture(error, { path: event.url.pathname });
if (status === 404) return Response.redirect(new URL('/', event.url), 302);
if (status >= 500) return { status, message: 'Something went wrong.' };
};If the hook itself throws, Mochi logs the secondary error and renders the error page with the original status/message. Not called for API-route errors.
Fallback behavior
If the user’s errorPage component itself throws during render, Mochi returns a plain-text response that mentions both the original error and the secondary render failure — the error page cannot crash the server.