Error handler
React 19 introduced onCaughtError, onUncaughtError, and onRecoverableError callbacks on createRoot and hydrateRoot. These are root-level error handlers that catch errors without requiring an error boundary wrapper.
flareReactErrorHandler is a wrapper function that returns a callback compatible with these handlers. It automatically reports errors to Flare with React-specific context, including structured component stack traces. It also handles non-Error values (strings, objects) by converting them to proper Error instances.
Basic usage
Pass flareReactErrorHandler() to the error callbacks when creating your root:
import { flareReactErrorHandler } from '@flareapp/react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'), {
onCaughtError: flareReactErrorHandler(),
onUncaughtError: flareReactErrorHandler(),
onRecoverableError: flareReactErrorHandler(),
});
root.render(<App />);
Callback lifecycle
The handler supports the same callback pattern as the error boundary, with three hooks that fire at different stages:
beforeEvaluate- called after the error is converted to anError, before building the component stack context. Use this to attach custom context to Flare (e.g. user info, feature flags).beforeSubmit- called with the built context. Return a (possibly modified) context object to filter or enrich the report before it is sent. See the error boundary docs for the context type shape.afterSubmit- called after the error is reported to Flare. Note that the report is sent asynchronously, so this callback runs after the report is initiated, not after the network request completes. Use this for side effects like logging or showing a toast.
All three callbacks receive { error, errorInfo }, and beforeSubmit / afterSubmit additionally receive context. Unlike the error boundary, errorInfo here is not an instance of React's ErrorInfo class. It is the plain object React passes to onCaughtError, onUncaughtError, and onRecoverableError, shaped as { componentStack?: string }.
The callbacks are not wrapped in a try/catch. If a hook throws, the error will bubble out of the React error callback, so keep the logic defensive.
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 — see Filtering errors for the full execution order.
import { flare } from '@flareapp/js';
import { flareReactErrorHandler } from '@flareapp/react';
const root = createRoot(document.getElementById('root'), {
// Errors caught by an Error Boundary
onCaughtError: flareReactErrorHandler({
afterSubmit: ({ error, errorInfo }) => {
console.warn('Caught error:', error);
},
}),
// Errors NOT caught by any Error Boundary
onUncaughtError: flareReactErrorHandler({
beforeEvaluate: ({ error }) => {
flare.addContext('user', { id: currentUser.id });
},
afterSubmit: ({ error }) => {
console.error('Uncaught error:', error);
},
}),
// Errors React recovers from automatically (e.g. hydration mismatches)
onRecoverableError: flareReactErrorHandler(),
});
root.render(<App />);
Usage with hydrateRoot
If your app uses server-side rendering (Next.js, Remix, etc.), you can use flareReactErrorHandler with hydrateRoot the same way:
import { flareReactErrorHandler } from '@flareapp/react';
import { hydrateRoot } from 'react-dom/client';
hydrateRoot(document.getElementById('root'), <App />, {
onUncaughtError: flareReactErrorHandler(),
onRecoverableError: flareReactErrorHandler(),
});
Compatibility with react-error-boundary
flareReactErrorHandler() returns a callback that matches the onError prop signature of the popular react-error-boundary library. If you're already using that library, you can report errors to Flare without switching to FlareErrorBoundary:
import { ErrorBoundary } from 'react-error-boundary';
import { flareReactErrorHandler } from '@flareapp/react';
<ErrorBoundary
onError={flareReactErrorHandler()}
fallback={<p>Something went wrong.</p>}
>
<App />
</ErrorBoundary>
When to use the error handler vs. the error boundary
| Error boundary | Error handler | |
|---|---|---|
| React version | 16+ | 19+ |
| Catches render errors | Yes | Yes |
| Displays fallback UI | Yes | No |
| Reset capability | Yes | No |
Works with createRoot callbacks |
No | Yes |
You can use both together: the error boundary for displaying fallback UI and the error handler for catching errors at the root level. Note that onCaughtError is omitted here because the FlareErrorBoundary already reports caught errors, and adding onCaughtError would cause them to be reported twice.
import { FlareErrorBoundary, flareReactErrorHandler } from '@flareapp/react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'), {
// onCaughtError is omitted because FlareErrorBoundary already handles these.
onUncaughtError: flareReactErrorHandler(),
onRecoverableError: flareReactErrorHandler(),
});
root.render(
<FlareErrorBoundary fallback={<p>Something went wrong.</p>}>
<App />
</FlareErrorBoundary>
);