The <ErrorBoundary> component captures errors thrown during rendering, including errors in Loader functions, and allows you to handle them gracefully with custom error UI. It also works seamlessly with server side streaming and when using loaders on the client.

import { ErrorBoundary, useRoute, useLoader } from 'firebolt' export default function Train() { return ( <ErrorBoundary fallback={<TrainError />}> <Suspense fallback={<div>Loading...</div>}> <TrainContent /> </Suspense> </ErrorBoundary> ) } function TrainContent() { const { id } = useRoute().params const loader = useLoader(getTrain, id) const train = loader.read() return ( <div> <div>Name: {train.name}</div> <div>Type: {train.type}</div> </div> ) } function TrainError({ code, id }) { return ( <div> <div>Error fetching train</div> <div>Code: {code}</div> <div>ID: {id}</div> </div> ) } export async function getTrain(ctx, id) { const train = await ctx.db('cars').where({ id }).first() // example non-operational error (ctx.foo is undefined) ctx.foo.bar.baz = 'yoohoo' // example operational error if (!train) ctx.error('NOT_FOUND') }

All non-operational errors are logged to stdout on the server with a unique id. The Error Boundary fallback receives an id prop to help reconcile errors in your logs.

The Context object provides a method to throw an operational error that includes a code, allowing you to provide contextual information to users. Operational errors are not logged to stdout.


The component to be rendered when an error is caught.

You can use the fallback prop a number of different ways for convenience:

// with a component <ErrorBoundary fallback={<MyError/>}/> // with jsx <ErrorBoundary fallback={<div>Error</div>} /> // with a function <ErrorBoundary fallback={err => <div>{err.code}</div>} />