React4 min read

React Error Boundaries in Production: Best Practices

Author:Rutik Vasani

What are React Error Boundaries?

A React Error Boundary is a React component that catches JavaScript errors anywhere in its child component tree, logs those errors, and displays a fallback UI instead of crashing the entire component tree (which typically results in a blank "white screen of death"). Introduced in React 16, they act similarly to a catch {} block but for React components, ensuring that an error in a minor UI element doesn't take down the entire application.


React error boundaries are your first line of defense against front-end crashes. When an unexpected error occurs during rendering, lifecycle methods, or in the constructors of any child component, the error boundary catches it. Without them, a single undefined variable in a deeply nested component can cause the entire React tree to unmount, leaving the user staring at a blank page.

In production, putting a single error boundary at the very top of your app is a rookie mistake. You must implement them per route or section and always report the error with the component stack and route context.

The Production-Ready Pattern

A basic error boundary is simple, but a production-ready one requires state management for recovery and robust logging capabilities.

import React from 'react';

class Boundary extends React.Component {
  state = { hasError: false, errorId: null }
  
  static getDerivedStateFromError(error) { 
    // Update state so the next render will show the fallback UI.
    return { hasError: true }; 
  }
  
  componentDidCatch(error, info) {
    // Generate a unique ID for this error occurrence
    const errorId = crypto.randomUUID();
    this.setState({ errorId });
    
    // Send error + info.componentStack + route to your tracker
    // In a real app, this goes to Relia, Sentry, Datadog, etc.
    console.error("Caught by boundary:", error, info.componentStack);
    
    // Example: sendToTracker(error, info, { route: window.location.pathname, errorId });
  }
  
  render() { 
    if (this.state.hasError) {
      return (
        <div className="error-fallback-container">
          <h2>Something went wrong in this section.</h2>
          <p>Error Reference: {this.state.errorId}</p>
          <button onClick={() => this.setState({hasError:false})}>
            Try Again
          </button>
        </div>
      );
    }
    return this.props.children; 
  }
}
export default Boundary;

Granular Wrapping is Crucial

Wrap your checkout, dashboard, settings, and navigation components separately. If a third-party widget in the sidebar crashes, the main content area (where the user is actually reading or buying) should remain fully functional. Granularity isolates failures, which is a core tenet of building resilient web applications.

What Error Boundaries Don't Catch

It's critical to understand the limitations of Error Boundaries. They do not catch errors for:

  1. Event Handlers: A crash inside an onClick or onSubmit handler will not trigger the boundary. React knows the event failed, but the component tree is still intact. You need try/catch blocks or global window.onerror listeners.
  2. Asynchronous Code: setTimeout, requestAnimationFrame, or API fetch promises. Unhandled promise rejections require a global unhandledrejection event listener (see our guide on /blog/unhandled-promise-rejection-nodejs-fix for similar concepts).
  3. Server-Side Rendering (SSR): Errors on the server must be handled by the server framework.
  4. Hydration Mismatches: If the server renders different HTML than the client expects, React logs a warning, but it doesn't trigger the boundary in the same way a runtime crash does.

To fully protect your app, Error Boundaries must be part of a broader observability strategy, addressing /blog/silent-frontend-failures-user-churn.

The Ultimate Autonomous Fix: Relia

Catching the error is only half the battle; fixing it is where the real cost lies. This is where Relia steps in as the ultimate autonomous bug fixing tool.

When your Error Boundary catches a crash, Relia doesn't just send you a stack trace. The captured crash arrives in your dashboard with a proposed code patch. Relia's AI analyzes the component stack, the surrounding code context, and the exact state that caused the crash, generating a ready-to-merge PR in minutes. You go from a user seeing a fallback UI to a deployed fix before they even have a chance to complain.

FAQ

Do I need Sentry for React errors?

Any tracker works if it captures component stack + user actions. Replay helps for invalid-state bugs. Relia goes one step further — the captured crash arrives with a proposed code patch, not just a replay to watch.

How do I avoid noise?

Ignore extension errors and ResizeObserver loops. Keep 100% of checkout/payment errors.

What is a good fallback UI?

Section-level retry + "report issue" that attaches session ID. Never full-page blank.

[ MORE ARTICLES ]

Read Next

View all →