Skip to content

Error Boundary

@granit/error-boundary provides framework-agnostic types for error context enrichment — breadcrumb trails, route info, and user identity. @granit/react-error-boundary wraps these into a headless React error boundary, a global error capture component, and a breadcrumb context provider.

All error reporting is delegated to @granit/logger — there is no built-in error UI. The consumer app provides its own fallback via renderFallback.

Peer dependencies: @granit/logger, react ^19

  • Directory@granit/error-boundary/ Breadcrumb, ErrorContextConfig types (framework-agnostic)
    • @granit/react-error-boundary GranitErrorBoundary, GlobalErrorCapture, ErrorContextProvider, hooks
PackageRoleDepends on
@granit/error-boundaryBreadcrumb, ErrorContextConfig, ErrorContextValue
@granit/react-error-boundaryGranitErrorBoundary, GlobalErrorCapture, ErrorContextProvider, useBreadcrumb@granit/error-boundary, @granit/logger, react
import { GranitErrorBoundary, GlobalErrorCapture, ErrorContextProvider } from '@granit/react-error-boundary';
import { createLogger } from '@granit/logger';
const logger = createLogger('app');
function App({ children }) {
return (
<ErrorContextProvider config={{
getRouteInfo: () => window.location.pathname,
getUserInfo: () => ({ id: currentUser.id }),
maxBreadcrumbs: 20,
}}>
<GlobalErrorCapture logger={logger} />
<GranitErrorBoundary
logger={logger}
renderFallback={(error, reset) => (
<div>
<h1>Something went wrong</h1>
<button onClick={reset}>Retry</button>
</div>
)}
>
{children}
</GranitErrorBoundary>
</ErrorContextProvider>
);
}
interface Breadcrumb {
category: string; // e.g. "navigation", "user", "api"
message: string;
timestamp: string; // ISO 8601
}
interface ErrorContextConfig {
getRouteInfo?: () => string;
getUserInfo?: () => { id: string };
maxBreadcrumbs?: number; // default: 20 (FIFO circular buffer)
}
interface ErrorContextValue {
readonly breadcrumbs: readonly Breadcrumb[];
addBreadcrumb: (category: string, message: string) => void;
getRouteInfo: () => string | undefined;
getUserInfo: () => { id: string } | undefined;
}

Provides contextual information (route, user, breadcrumbs) that is automatically attached to errors caught by GranitErrorBoundary and GlobalErrorCapture.

<ErrorContextProvider config={{
getRouteInfo: () => window.location.pathname,
getUserInfo: () => ({ id: user.id }),
maxBreadcrumbs: 20,
}}>
{children}
</ErrorContextProvider>

Headless React error boundary. Catches rendering errors, logs them via @granit/logger, and delegates UI to the renderFallback function.

interface ErrorBoundaryProps {
logger: Logger;
renderFallback: (error: Error, resetErrorBoundary: () => void) => React.ReactNode;
onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
children: React.ReactNode;
}

Invisible component that listens to window.onerror and window.onunhandledrejection. Deduplicates errors by message within a 1-second window. Logs via @granit/logger.

interface GlobalErrorCaptureProps {
logger: Logger;
onError?: (error: Error) => void;
}
function GlobalErrorCapture(props: GlobalErrorCaptureProps): null;

Returns the error context value from the nearest ErrorContextProvider.

function useErrorContext(): ErrorContextValue;

Convenience hook for adding breadcrumbs to the error context.

function useBreadcrumb(): {
addBreadcrumb: (category: string, message: string) => void;
};
graph LR
    Breadcrumbs["Breadcrumbs"] --> Context["ErrorContext"]
    Route["Route info"] --> Context
    User["User info"] --> Context
    Context --> Boundary["GranitErrorBoundary"]
    Context --> Global["GlobalErrorCapture"]
    Boundary --> Logger["@granit/logger"]
    Global --> Logger

When an error is caught, the error context (breadcrumbs, route, user) is attached to the log entry for debugging.

CategoryKey exportsPackage
TypesBreadcrumb, ErrorContextConfig, ErrorContextValue@granit/error-boundary
Error boundaryGranitErrorBoundary@granit/react-error-boundary
Global captureGlobalErrorCapture@granit/react-error-boundary
Context providerErrorContextProvider, useErrorContext()@granit/react-error-boundary
Breadcrumb hookuseBreadcrumb()@granit/react-error-boundary
  • Logger — Error boundary logs via @granit/logger
  • Tracing — Errors are correlated with traces when TracingProvider is active