中文文档 | English
A library for handling React Native errors, providing error boundary and global error handling functionality.
- 🛡️ Error Boundary: Catch JavaScript errors in React component tree
- 🌐 Global Error Handling: Catch unhandled JavaScript errors and Promise rejections
- 🔧 Promise Patching: Resolve React Native Promise version mismatch issues
- 📱 Cross-platform Support: Support for iOS and Android platforms
- 🎨 Custom Error Pages: Support for custom error fallback components
- 📊 Detailed Error Information: Provide error stack, timestamp, platform info and other context
src/
├── components/
│ └── ErrorBoundary/ # Error boundary component
│ ├── DefaultFallback/ # Default error fallback component
│ │ ├── index.tsx # Component implementation
│ │ └── styles.ts # Style definitions
│ └── index.tsx # Main error boundary component
├── handlers/ # Error handlers
│ ├── setupErrorUtilsGlobalHandler.ts # Global error handler
│ └── setupUnhandledRejectionsTracking.ts # Unhandled rejection tracking
├── types/
│ └── index.ts # TypeScript type definitions
├── utils/ # Utility functions
│ ├── environment.ts # Environment detection
│ ├── error.ts # Error handling utilities
│ ├── promisePolyfill.ts # Promise patching
│ ├── setupReactNativeErrorHandlers.ts # Main setup function
│ └── toolkit.ts # Common utilities
├── __tests__/ # Test files
│ └── index.test.tsx
└── index.tsx # Main entry file
# npm
npm install react-native-error-handler
# yarn
yarn add react-native-error-handler
Error boundaries are used to catch JavaScript errors in React component tree, preventing the entire app from crashing.
import React from 'react';
import { ErrorBoundary } from 'react-native-error-handler';
// Custom error fallback component
const CustomFallback = ({ resetError }) => (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>An error occurred, please try again</Text>
<Button title="Retry" onPress={resetError} />
</View>
);
function App() {
return (
<ErrorBoundary
FallbackComponent={CustomFallback}
onError={(errorInfo) => {
console.log('Error caught:', errorInfo);
// You can report errors to error monitoring services here
// reportError(errorInfo);
}}
>
<YourAppComponents />
</ErrorBoundary>
);
}Set up global error handlers to catch unhandled JavaScript errors and Promise rejections.
import { setupReactNativeErrorHandlers } from 'react-native-error-handler';
// Set up global error handling at app startup
setupReactNativeErrorHandlers(
{
enableGlobalErrorHandler: true, // Enable global error handling
enableUnhandledRejection: true, // Enable unhandled Promise rejection handling
patchGlobalPromise: true, // Patch global Promise
enableInDev: true, // Enable in development mode
},
(errorInfo) => {
console.log('Global error:', errorInfo);
// Report errors to error monitoring services
// reportError(errorInfo);
}
);import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import {
ErrorBoundary,
setupReactNativeErrorHandlers
} from 'react-native-error-handler';
// Custom error fallback component
const CustomErrorFallback = ({ resetError }) => (
<View style={styles.errorContainer}>
<Text style={styles.errorTitle}>Application Error</Text>
<Text style={styles.errorMessage}>
Sorry, the application encountered a problem. Please click the retry button to reload.
</Text>
<Button title="Retry" onPress={resetError} />
</View>
);
// Set up global error handling
setupReactNativeErrorHandlers(
{
enableGlobalErrorHandler: true,
enableUnhandledRejection: true,
patchGlobalPromise: true,
enableInDev: true,
},
(errorInfo) => {
console.error('Global error caught:', errorInfo);
// Error information includes the following fields:
// - error: Error object
// - isFatal: Whether it's a fatal error
// - type: Error type ('error' | 'unhandledrejection')
// - timestamp: Error occurrence timestamp
// - context: Additional context information (platform, stack, etc.)
// You can report errors to error monitoring services here
// reportError(errorInfo);
}
);
function App() {
return (
<ErrorBoundary
FallbackComponent={CustomErrorFallback}
onError={(errorInfo) => {
console.error('Component error caught:', errorInfo);
// Handle component-level errors
}}
>
<View style={styles.container}>
<Text>Your app content</Text>
{/* Your app components */}
</View>
</ErrorBoundary>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
errorContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
errorTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
errorMessage: {
fontSize: 14,
textAlign: 'center',
marginBottom: 20,
},
});interface ErrorHandlerOptions {
/** Whether to enable global error handling */
enableGlobalErrorHandler?: boolean;
/** Whether to enable unhandled Promise rejection handling */
enableUnhandledRejection?: boolean;
/** Whether to enable in development mode */
enableInDev?: boolean;
/** Whether to patch global Promise (to resolve React Native Promise version mismatch issues) */
patchGlobalPromise?: boolean;
}interface ErrorInfo {
/** Error object */
error: Error;
/** Whether it's a fatal error */
isFatal?: boolean;
/** Error type */
type: 'error' | 'unhandledrejection';
/** Error occurrence timestamp */
timestamp: number;
/** Additional context information */
context?: Record<string, any>;
}-
Use ErrorBoundary at the root component
// In App.js or index.js <ErrorBoundary onError={handleError}> <App /> </ErrorBoundary>
-
Set up global error handling at app startup
// At the top of index.js or App.js import { setupReactNativeErrorHandlers } from 'react-native-error-handler'; setupReactNativeErrorHandlers( { enableGlobalErrorHandler: true, enableUnhandledRejection: true }, (errorInfo) => { // Report errors to monitoring system } );
-
Error reporting integration
const reportError = (errorInfo) => { // Send to error monitoring services (e.g., Bugsnag, Firebase Crashlytics, etc.) // Example: Using Sentry // Sentry.captureException(errorInfo.error, { // extra: { // isFatal: errorInfo.isFatal, // type: errorInfo.type, // timestamp: errorInfo.timestamp, // context: errorInfo.context, // } // }); // Example: Report to custom monitoring service fetch('/api/errors', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ error: errorInfo.error.message, stack: errorInfo.error.stack, isFatal: errorInfo.isFatal, type: errorInfo.type, timestamp: errorInfo.timestamp, context: errorInfo.context, }), }); };
- Development Environment: By default, global error handling is disabled in development mode, can be enabled with
enableInDev: true - Promise Patching: If you encounter Promise-related issues, it's recommended to enable
patchGlobalPromise: true - Error Boundary Limitations: Error boundaries can only catch errors in child component trees, cannot catch the following errors:
- Errors in event handlers
- Errors in asynchronous code (such as setTimeout, Promise)
- Errors during server-side rendering
- Errors in the error boundary itself
-
Error boundary not working
- Ensure ErrorBoundary wraps components that might throw errors
- Check if the component is imported correctly
-
Global error handling not effective
- Ensure
setupReactNativeErrorHandlersis called early in app startup - Check if configuration options are set correctly
- Ensure
-
Promise-related errors
- Enable
patchGlobalPromise: trueoption - Check React Native version compatibility
- Enable
| Property | Type | Required | Description |
|---|---|---|---|
onError |
(errorInfo: ErrorInfo) => void |
No | Error callback function |
FallbackComponent |
ComponentType<{ resetError: () => void }> |
No | Custom error fallback component |
| Parameter | Type | Default | Description |
|---|---|---|---|
options.enableGlobalErrorHandler |
boolean |
true |
Enable global error handling |
options.enableUnhandledRejection |
boolean |
true |
Enable unhandled Promise rejection handling |
options.enableInDev |
boolean |
true |
Enable in development mode |
options.patchGlobalPromise |
boolean |
true |
Patch global Promise |
callback |
ErrorCallback |
- | Error callback function |
MIT
Made with create-react-native-library
Some code comes from sentry-react-native
Some code comes from es-toolkit