The Proliferate SDK provides React-specific components for catching and reporting errors in your React component tree.
Installation
The React integration is included in the main SDK package:
npm install @proliferate/sdk
Import from the /react subpath:
import {
ProliferateErrorBoundary,
withErrorBoundary,
useErrorBoundary,
} from '@proliferate/sdk/react';
ProliferateErrorBoundary
A React Error Boundary component that automatically captures errors to Proliferate, including component stack traces.
Basic Usage
import { ProliferateErrorBoundary } from '@proliferate/sdk/react';
function App() {
return (
<ProliferateErrorBoundary fallback={<div>Something went wrong</div>}>
<MyComponent />
</ProliferateErrorBoundary>
);
}
Props
Child components to render
fallback
ReactNode | ((error: Error, reset: () => void) => ReactNode)
Fallback UI when error occurs
onError
(error: Error, errorInfo: ErrorInfo) => void
Callback when error is caught
Callback when boundary resets
Keys that trigger reset when changed
Fallback with Reset Function
Provide a function as fallback to access the error and reset mechanism:
<ProliferateErrorBoundary
fallback={(error, reset) => (
<div className="error-container">
<h2>Something went wrong</h2>
<p>{error.message}</p>
<button onClick={reset}>Try again</button>
</div>
)}
>
<MyComponent />
</ProliferateErrorBoundary>
Error Callback
Add custom error handling alongside Proliferate capture:
<ProliferateErrorBoundary
onError={(error, errorInfo) => {
// Send to analytics
analytics.track('react_error', {
message: error.message,
componentStack: errorInfo.componentStack,
});
}}
fallback={<ErrorFallback />}
>
<MyComponent />
</ProliferateErrorBoundary>
Reset on Route Change
Use resetKeys to automatically reset the boundary when navigating:
import { useLocation } from 'react-router-dom';
function App() {
const location = useLocation();
return (
<ProliferateErrorBoundary
resetKeys={[location.pathname]}
fallback={<ErrorPage />}
>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</ProliferateErrorBoundary>
);
}
withErrorBoundary HOC
Wrap any component with an error boundary using the higher-order component:
import { withErrorBoundary } from '@proliferate/sdk/react';
function MyComponent(props: MyComponentProps) {
// Component that might throw
return <div>...</div>;
}
// Basic usage
const SafeComponent = withErrorBoundary(
MyComponent,
<div>Component failed to load</div>
);
// With function fallback
const SafeComponent = withErrorBoundary(
MyComponent,
(error, reset) => (
<div>
<p>Error: {error.message}</p>
<button onClick={reset}>Retry</button>
</div>
)
);
// With error callback
const SafeComponent = withErrorBoundary(
MyComponent,
<ErrorFallback />,
(error, errorInfo) => {
console.error('Component error:', error);
}
);
Signature
function withErrorBoundary<P extends object>(
WrappedComponent: React.ComponentType<P>,
fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode),
onError?: (error: Error, errorInfo: ErrorInfo) => void
): React.FC<P>;
useErrorBoundary Hook
Programmatically trigger the nearest error boundary:
import { useErrorBoundary } from '@proliferate/sdk/react';
function MyComponent() {
const { showBoundary } = useErrorBoundary();
const handleAsyncError = async () => {
try {
await riskyAsyncOperation();
} catch (error) {
// Trigger the nearest error boundary
showBoundary(error as Error);
}
};
return <button onClick={handleAsyncError}>Do risky thing</button>;
}
This is useful for catching errors in event handlers, async operations, and callbacks—places where React error boundaries don’t automatically catch errors.
What Gets Captured
When an error is caught by ProliferateErrorBoundary, the SDK captures:
| Field | Description |
|---|
error.name | Error type (e.g., TypeError, ReferenceError) |
error.message | Error message |
error.stack | JavaScript stack trace |
componentStack | React component stack trace |
reactErrorBoundary | Flag indicating React boundary capture |
The component stack shows the React component hierarchy:
at BrokenComponent (src/components/BrokenComponent.tsx:15:5)
at div
at ErrorBoundary
at App (src/App.tsx:8:3)
Best Practices
1. Wrap at Multiple Levels
Use multiple boundaries to isolate failures:
function App() {
return (
<ProliferateErrorBoundary fallback={<AppErrorPage />}>
<Header />
<main>
<ProliferateErrorBoundary fallback={<SidebarError />}>
<Sidebar />
</ProliferateErrorBoundary>
<ProliferateErrorBoundary fallback={<ContentError />}>
<Content />
</ProliferateErrorBoundary>
</main>
<Footer />
</ProliferateErrorBoundary>
);
}
2. Error Boundaries Don’t Catch Everything
Error boundaries don’t catch errors in:
- Event handlers
- Async code (setTimeout, promises)
- Server-side rendering
- Errors in the boundary itself
Use try/catch with captureException for these:
import Proliferate from '@proliferate/sdk';
function MyComponent() {
const handleClick = () => {
try {
riskyOperation();
} catch (error) {
Proliferate.captureException(error);
// Handle gracefully
}
};
return <button onClick={handleClick}>Click me</button>;
}
Or use the useErrorBoundary hook to trigger the boundary:
function MyComponent() {
const { showBoundary } = useErrorBoundary();
const handleClick = async () => {
try {
await riskyAsyncOperation();
} catch (error) {
showBoundary(error as Error);
}
};
return <button onClick={handleClick}>Click me</button>;
}
3. Provide Useful Fallbacks
Make fallback UIs actionable:
<ProliferateErrorBoundary
fallback={(error, reset) => (
<div className="error-card">
<h3>This section couldn't load</h3>
<p>We've been notified and are looking into it.</p>
<div className="error-actions">
<button onClick={reset}>Try again</button>
<button onClick={() => window.location.reload()}>
Refresh page
</button>
</div>
</div>
)}
>
<Dashboard />
</ProliferateErrorBoundary>
TypeScript
All types are exported:
import type { ErrorBoundaryProps } from '@proliferate/sdk/react';
import type { ErrorInfo } from 'react';
const errorHandler = (error: Error, errorInfo: ErrorInfo) => {
console.log(errorInfo.componentStack);
};