ErrorBoundary

The ErrorBoundary component is an optional error boundary for catching and handling errors in your React component tree. It prevents the entire app from crashing when an error occurs and allows you to display a custom fallback UI.

ℹ️

This component is completely optional. The library works perfectly without it. It’s provided as a convenience for better error handling in your application.

⚠️

Cross-Platform Compatible: The ErrorBoundary component doesn’t render any platform-specific UI (no HTML or React Native elements). You must provide your own fallback UI for both web and React Native.


Importing

To use the ErrorBoundary, import it from @blue-functor/remodel:

import { ErrorBoundary } from '@blue-functor/remodel';

Parameters

ParameterTypeRequiredDescription
childrenReactNodeYesThe component tree to wrap and protect from errors.
fallback(error: Error, errorInfo: ErrorInfo) => ReactNodeRequired for productionCustom fallback UI to render when an error occurs. Must use your platform’s UI components (HTML for web, React Native components for mobile).
onError(error: Error, errorInfo: ErrorInfo) => voidNoOptional callback to handle errors (e.g., logging to external services like Sentry).

Returns

Renders children normally, or the fallback UI when an error is caught. Returns null if no fallback is provided and an error occurs.


Example Usage

React Web Application

src/App.tsx
import React from 'react';
import { ErrorBoundary } from '@blue-functor/remodel';
 
function App() {
  return (
    <ErrorBoundary
      fallback={(error, errorInfo) => (
        <div style={{ padding: '20px', color: 'red' }}>
          <h1>Something went wrong</h1>
          <details>
            <summary>Error Details</summary>
            <pre>{error.message}</pre>
            <pre>{errorInfo.componentStack}</pre>
          </details>
        </div>
      )}
      onError={(error, errorInfo) => {
        // Send to logging service
        console.error('Error caught:', error, errorInfo);
      }}
    >
      <YourApp />
    </ErrorBoundary>
  );
}

React Native Application

src/App.tsx
import React from 'react';
import { View, Text, ScrollView } from 'react-native';
import { ErrorBoundary } from '@blue-functor/remodel';
 
function App() {
  return (
    <ErrorBoundary
      fallback={(error, errorInfo) => (
        <View style={{ flex: 1, padding: 20, backgroundColor: '#ffebee' }}>
          <Text style={{ fontSize: 20, fontWeight: 'bold', color: '#c62828' }}>
            Something went wrong
          </Text>
          <ScrollView style={{ marginTop: 20 }}>
            <Text style={{ fontSize: 14, color: '#666' }}>{error.message}</Text>
            <Text style={{ fontSize: 12, color: '#999', marginTop: 10 }}>
              {errorInfo.componentStack}
            </Text>
          </ScrollView>
        </View>
      )}
      onError={(error, errorInfo) => {
        // Log to Sentry, Firebase Crashlytics, etc.
        logErrorToService(error, errorInfo);
      }}
    >
      <YourApp />
    </ErrorBoundary>
  );
}

With External Error Logging (Sentry Example)

src/App.tsx
import React from 'react';
import { ErrorBoundary } from '@blue-functor/remodel';
import * as Sentry from '@sentry/react';
 
function App() {
  return (
    <ErrorBoundary
      fallback={(error) => (
        <div>
          <h1>We're sorry - something went wrong</h1>
          <p>{error.message}</p>
        </div>
      )}
      onError={(error, errorInfo) => {
        Sentry.captureException(error, {
          contexts: { react: { componentStack: errorInfo.componentStack } },
        });
      }}
    >
      <YourApp />
    </ErrorBoundary>
  );
}

Features

  1. Optional Component:

    • The library works perfectly without ErrorBoundary.
    • Use it only if you want error handling in your component tree.
  2. Cross-Platform Compatible:

    • Doesn’t render any platform-specific elements.
    • Works in both React web and React Native applications.
    • You provide the UI components appropriate for your platform.
  3. Custom Error Handling:

    • Integrate with error logging services like Sentry, Bugsnag, or Firebase Crashlytics.
    • Handle errors in any custom way via the onError callback.
  4. Development Friendly:

    • In development, errors are logged to the console with detailed component stack traces.
    • In production, only your custom onError handler is called (no console logging).

Best Practices

Do

// Provide a fallback UI for production
<ErrorBoundary
  fallback={(error) => <YourCustomErrorUI error={error} />}
  onError={(error) => logToService(error)}
>
  <App />
</ErrorBoundary>
 
// Use platform-specific components in fallback
// Web: <div>, <h1>, <p>, etc.
// React Native: <View>, <Text>, etc.
 
// Log errors to external services
onError={(error, errorInfo) => {
  Sentry.captureException(error);
}}

Don’t

// Don't use without a fallback in production
<ErrorBoundary> {/* ❌ No fallback - will return null on error */}
  <App />
</ErrorBoundary>
 
// Don't mix platform-specific components
<ErrorBoundary
  fallback={() => <div>Error</div>} // ❌ Won't work in React Native
>
 
// Don't use HTML in React Native or vice versa

How It Works

  1. Error Catching:

    • Uses React’s componentDidCatch lifecycle method to catch errors in child components.
    • Prevents the error from bubbling up and crashing the entire app.
  2. Fallback Rendering:

    • When an error is caught, renders your custom fallback UI instead of the broken component tree.
    • If no fallback is provided, returns null and logs a warning in development.
  3. Error Reporting:

    • Calls your onError callback with the error and component stack information.
    • In development, also logs to console if no onError is provided.

Notes

  • Not Required: The ErrorBoundary is optional. All other parts of @blue-functor/remodel work without it.

  • Production Requirement: You must provide a fallback prop for production use, as there’s no default UI (to maintain cross-platform compatibility).

  • Error Types: Error boundaries catch errors during rendering, in lifecycle methods, and in constructors. They do not catch errors in event handlers or async code - handle those separately.

  • Multiple Boundaries: You can use multiple error boundaries at different levels of your component tree for granular error handling.

The ErrorBoundary component provides a production-ready way to handle React errors gracefully, preventing your app from crashing and allowing you to log errors to external services for monitoring and debugging.