Skip to main content

Error Boundaries

Generates: Logs

Learn how to catch and handle React component rendering errors using Error Boundaries.

Setup

Ensure the Pulse SDK is properly initialized. See Quick Start for setup instructions.

What are Error Boundaries?

Error Boundaries are React components that catch JavaScript errors anywhere in their child component tree. They help prevent your entire app from crashing when a component encounters an error during rendering.

Error Boundaries catch:

  • Errors during component rendering
  • Errors in lifecycle methods
  • Errors in constructors
  • Null/undefined errors

Error Boundaries do NOT catch:

  • Errors in event handlers (use try-catch instead)
  • Asynchronous code (use try-catch or Promise.catch)
  • Server-side rendering errors
  • Errors in the error boundary itself

Basic Usage

Simple Error Boundary

Wrap components to catch rendering errors. Without a fallback, errors are marked as fatal:

import { Pulse } from '@horizoneng/pulse-react-native';

function App() {
return (
<Pulse.ErrorBoundary>
<YourComponent />
</Pulse.ErrorBoundary>
);
}

Error Boundary with Fallback UI

Provide a fallback UI to display when an error occurs. Errors with fallback are marked as non-fatal:

function ErrorFallback({ error, componentStack }) {
return (
<View style={{ padding: 20 }}>
<Text style={{ fontSize: 18, fontWeight: 'bold' }}>
Something went wrong
</Text>
<Text style={{ marginTop: 10 }}>
{error instanceof Error ? error.message : String(error)}
</Text>
</View>
);
}

<Pulse.ErrorBoundary fallback={ErrorFallback}>
<YourComponent />
</Pulse.ErrorBoundary>

You can also use a simple component as fallback:

<Pulse.ErrorBoundary fallback={<Text>⚠️ Something went wrong</Text>}>
<YourComponent />
</Pulse.ErrorBoundary>

Error Boundary with Callback

Use the onError callback for additional error handling:

<Pulse.ErrorBoundary 
fallback={<Text>Something went wrong</Text>}
onError={(error, componentStack) => {
// Log to console
console.log('Render error:', error);

// Perform custom actions
logToAnalytics(error);

// Access component stack
console.log('Component stack:', componentStack);
}}
>
<YourComponent />
</Pulse.ErrorBoundary>

Higher-Order Component (HOC)

Wrap individual components using the HOC pattern:

const SafeComponent = Pulse.withErrorBoundary(
UserProfile,
{
fallback: <Text>⚠️ Profile failed to load</Text>,
onError: (error, componentStack) => {
console.log('Profile component error:', error);
},
}
);

// Use the wrapped component
<SafeComponent userId="123" />

Example with inline component:

const WrappedComponent = Pulse.withErrorBoundary(
({ name, shouldThrow }: { name: string, shouldThrow: boolean }) => {
if (shouldThrow) {
throw new Error('Error in component!');
}
return <Text>Hello, {name}!</Text>;
},
{
fallback: <Text>⚠️ Component failed</Text>,
}
);

Fatal vs Non-Fatal Errors

The error fatality is determined by whether a fallback UI is provided:

Fatal errors (no fallback):

<Pulse.ErrorBoundary>
<YourComponent />
</Pulse.ErrorBoundary>
// error.fatal = true

Non-fatal errors (with fallback):

<Pulse.ErrorBoundary fallback={<Text>Error</Text>}>
<YourComponent />
</Pulse.ErrorBoundary>
// error.fatal = false

Sample Telemetry

Error boundaries generate log records with the following structure:

Type: Logs
Body: Error message
pulse.type: non_fatal

Example: Fatal Error (No Fallback)

{
"body": "Cannot read property 'name' of undefined",
"timestamp": "2025-11-27T13:43:02.851Z",
"attributes": {
"pulse.type": "non_fatal",
"error.fatal": true,
"error.source": "js",
"exception.type": "Error",
"exception.message": "Cannot read property 'name' of undefined",
"exception.stacktrace": "Error: Cannot read property...\n at UserProfile (...)",
"platform": "react-native",
"session.id": "dce09977c69b0a5c15aa5fd01f817514",
"thread.id": "68",
"thread.name": "mqt_v_js"
},
"span_id": "1eac884bed255470",
"trace_flags": 1,
"trace_id": "5ed3bda81ddf0525b0fccae32cac6a26"
}

Example: Non-Fatal Error (With Fallback)

{
"body": "Failed to render component",
"timestamp": "2025-11-27T13:42:55.417Z",
"attributes": {
"pulse.type": "non_fatal",
"error.fatal": false,
"error.source": "js",
"exception.type": "Error",
"exception.message": "Failed to render component",
"exception.stacktrace": "Error: Failed to render...\n at componentDidCatch (...)",
"platform": "react-native",
"session.id": "dce09977c69b0a5c15aa5fd01f817514"
},
"span_id": "",
"trace_flags": 0,
"trace_id": ""
}

Note: When an error occurs during an active span, span_id and trace_id are automatically included for correlation. All error boundary events include global attributes (service, device, OS, session, etc.) in the resources object. See Global Attributes for details.