Error Handling with React Error Boundary

Wednesday, February 12, 2025

As a JavaScript library, React is used for designing user interfaces and provides a wide range of features including a protective layer called the error boundary. Expert React developers leverage it to identify and manage errors within components and prevent them from application crashing. 

Using error boundaries, React development companies can display informative error messages in the fallback user interface, log error information, and make sure your app has a high fault tolerance. 

Error boundaries are largely used to tackle unexpected problems. This article explains the uses and implementation patterns of them.

1. What is an Error Boundary in React?

Error boundaries play a crucial role in error handling in React applications. Error Boundary is simply a React component, used to prevent JavaScript errors in its child component tree. Pick a component tree you want to protect and then wrap the Error boundary around it. 

The error border will detect the errors when they happen, log them, and then display them in the fallback user interface of that component tree. Using error boundaries helps prevent errors from propagating throughout the component tree and crashing the entire app. 

Before the error boundaries were built, the errors could spread and multiply over time within the component, leading to broken UIs, and significantly harming the user experience. Now, you can restrict the errors and handle them effectively using error boundaries. 

To use the error boundaries, your class component must include either or both of the following lifecycle methods: 

  • static getDerivedStateFromError(): After an error occurs, this method is implemented to render a fallback UI. 
  • componentDidCatch(): This method logs all the information related to the error. 

Using error boundaries, you can make your apps more stable and reliable. It prevents errors from crashing your app and helps you deliver an enhanced UX.

2. Common Use Cases of Error Boundaries

A React component lifecycle consists of various stages: including initialization, mounting, updating, and unmounting. We just discussed the componentDidCatch lifecycle method. It’s used during the updating stage right after the descendant component throws the error. Then it gets two arguments: info and error. 

The object comprising the component stack trace is an info argument and the error that was thrown away. See the below code example of the error boundary.

import React from "react";
class ErrorBoundary extends React.Component {
 constructor(props) {
   super(props);
   this.state = { hasError: false };
 }
 componentDidCatch(error, info) {
   this.setState({ hasError: true });
   console.log(error, info);
 }
 render() { 
   if (this.state.hasError) {
     return 

Something went wrong.

; } return this.props.children; } }

In the componentDidCatch method, we have to set the has-error property to true and log the error and info arguments in the console. So, this was the general implementation of the error boundary, which is used for handling different kinds of errors effectively. 

3. How to Use React-Error-Boundary?

React-error-boundary simplifies managing JavaScript errors in React components. In comparison to React Hooks, it adopts a more modern approach that aligns well with the latest trends in React development. This section explores various ways to implement React-error-boundary effectively.

3.1 ErrorBoundary Component

You have to wrap the ErrorBoundary component around the React components to stop errors from crashing the React application. There are multiple props available in the React-error-boundary and this component uses them effectively to handle errors. 

FallbackComponent

If there’s an error within the error boundaries, you can render a custom component with the FallbackComponent prop. This enables you to display the error messages and offer necessary actions as it enables you to design an informative yet visually appealing user interface. 

Code example for ErrorBoundary component:

"use client";
import React from "react";
import { ErrorBoundary } from "react-error-boundary";
// Fallback component
function Fallback({ error, resetErrorBoundary }: any) {
  return (
    

Something went wrong:

{error.message}
); } // Example Component that may throw an error function ExampleComponent({ throwError }: any) { if (throwError) { throw new Error("Simulated error"); } return
All good here!
; } function App() { const [shouldThrowError, setShouldThrowError] = React.useState(true); return ( { // Reset the state of your app so the error doesn't happen again setShouldThrowError(false); }} > ); } export default App;

fallbackRender

It allows you to display the custom error fallback UI by defining a specific render function. With the use of FallbackComponent, you get more advanced error-handling logic and greater control over the rendering process. 

onError

The onError prop accepts the callback function that is triggered when the error boundary catches an error. You can log the errors and send reports to external services using onError. Code for logging errors with onError prop:

"use client";
import React from "react";
import { ErrorBoundary } from "react-error-boundary";
// Custom Fallback Component
const ErrorFallback = ({ error, resetErrorBoundary }: any) => {
  return (
    

Oops! Something went wrong.

); }; const logError = (error: Error, info: React.ErrorInfo) => { // Do something with the error, e.g. log to an external API console.error("Error logged:", error, info); }; // Example Component that might throw an error const ExampleApplication = () => { throw new Error("Simulated error in ExampleApplication"); return
Example Application
; }; const App = () => { return ( logError(error, info)} > ); }; export default App;

onReset 

Whenever the error boundary resets after the occurrence of the error, onReset prop triggers a callback function. It helps carry out cleanup actions and updates the component’s state after recovering from the error. 

fallbackProps

If you have to pass some additional props to the fallbackRender function or the FallbackComponent, fallbackProps can assist you. It enables you to deliver a clear context and additional information regarding the error to the fallback UI. You can render the default error message of “something went wrong” in the simplest manner using this prop.

"use client";
import React from "react";
import { ErrorBoundary } from "react-error-boundary";

// Custom Fallback Component
const CustomFallback = ({ error, resetErrorBoundary, additionalInfo }: any) => {
  return (
    

Oops! Something went wrong.

{additionalInfo}

{error.message}
); }; // Example Component that might throw an error const ExampleApplication = () => { throw new Error("Simulated error in ExampleApplication"); return
Example Application
; }; const App = () => { return ( ( )} > ); }; export default App;

retry

This boolean value indicates whether the operations that caused the error can be retried by the error boundary. The resetErrorBoundary function is called during the retrial of the operation if the value is set to true. 

3.2 useErrorBoundary Hook

The useErrorBoundary hook is a part of the react-error-boundary package and offers a functional and concise approach to creating error boundaries in your React application. First, import the hook and then execute it using the following command:

import React from "react";
import { ErrorBoundary, useErrorBoundary } from "react-error-boundary";

const ErrorFallback = ({ error }: any) => {
  const { resetBoundary } = useErrorBoundary();
  return (
    

Oops! An error occurred: {error.message}

); }; const WeatherInfo = ({ city }: any) => { if (!city) { throw new Error("City name is mandatory to fetch the weather data"); } // Simulating fetching weather data return
Weather Information for: {city}
; }; const App = () => { const [city, setCity] = React.useState(null); return (

Weather Information

{ setCity("Ahmedabad"); // Set a default valid city on reset }} >
); }; export default App;

The user can reset the error boundary and attempt to generate the WeatherInfocomponent again with the resetBoundary function. You can also reset the component by passing this function to the onReset prop. 

3.3 withErrorBoundary Function as HOC

Although functional components and React Hooks are increasingly popular, there might be some instances where you have to work with a class component or a high-order component (HOC)  pattern. For that, the React-error-boundary package is offered with ErrorBoundary HOC. 

This HOC wraps the given component using the error boundary, so you no longer have to add any extra JSX to the component tree or change its implementation to add an error boundary to your components. You can use this component in the following way: 

import React from "react";
import { withErrorBoundary } from "react-error-boundary";

function MyComponent({ city }: any) {
  if (!city) {
    throw new Error("City is required!");
  }
  return 
City Name: {city}
; } function App() { const [city, setCity] = React.useState(""); function ErrorFallback({ error, resetErrorBoundary }: any) { return (

Oops! An error occurred: {error.message}

); } // Error Logging Function function logErrorToService(error: Error, info: React.ErrorInfo) { console.error("Logging error:", error, info); } // Reset Handler function handleReset() { console.log("Error boundary reset"); setCity("Ahmedabad"); } const MyComponentWithErrorBoundary = withErrorBoundary(MyComponent, { FallbackComponent: ErrorFallback, onError: logErrorToService, onReset: handleReset, resetKeys: ["city"], }); return ; } export default App;

The above code shows withErrorBoundary wrapping the MyComponent with an error boundary. The options object acts as the second argument to the withErrorBoundary. The same Props offered to the ErrorBoundary component can also be provided here. This example also proves that react-error-boundary is very flexible and can adapt various paradigms and coding styles in React development. 

4. Examples of Using Error Boundaries

The Error boundary component acts as a security layer for the application, preventing errors from the single component from crashing the entire application. So, even if a specific component encounters failures on your app, the users can continue to use it without any interruptions as the error boundary isolates those problems. 

Here in this example, the UserProfileis wrapped with the ErrorBoundary. The error appears when the userId passed as a prop to the component does not exist in the database or causes any internal server error. The ErrorBoundary detects the problem and displays a “Something went wrong” message in the fallback UI. The users can continue to use the app even in the instance of failure of the UserProfilecomponent. 

import React, { Component, ErrorInfo } from "react";


interface ErrorBoundaryState {
  hasError: boolean;
}

interface ErrorBoundaryProps {
  children: React.ReactNode;
}

class ErrorBoundary extends Component {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    // Update state so the next render will show the fallback UI
    return { hasError: true };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // You can also log the error to an error reporting service
    console.error("Error caught by ErrorBoundary: ", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return 

Something went wrong.

; } return this.props.children; } } export default ErrorBoundary;

The user is the state variable, initialized with the default value of null, in the below UserProfileComponent. The ErrorBoundary wraps around the UserProfilein the JSX code. The static userId is passed as a prop to the UserProfile component. 

import React, { useEffect, useState } from "react";

const UserProfile: React.FC = ({ userId }) => {
  const [user, setUser] = useState(null); // Replace 'any' with a proper user type if available
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchUserData = async () => {
      try {
        const response = await fetch(`https://api.example.com/users/${userId}`);
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        const data = await response.json();
        setUser(data);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    };
    if (userId) fetchUserData();
  }, [userId]);

  if (loading) {
    return 
Loading...
; } if (error) { throw new Error("Failed to fetch user data"); } return (

{user.name}

Email: {user.email}

Bio: {user.bio}

); }; export default UserProfile;
import React from “react”;
Import ErrorBoundary from “./ErrorBoundary”;
Import UserProfile from “./UserProfile”;

function App() {
  const userId = 1; // Example user ID

  return (
    

User Profile

); } export default App;

Here we have used error boundaries for asynchronous operations, like network requests. If the network requests fail, the error boundary can help manage it by providing the user with a fallback UI. 

As in the example, a UserProfile component helps you retrieve user information from the API. In case of an API call failure, the error boundary will show the “Something went wrong” message on the user’s screen and “FailedUnable to fetch user data” in the console. By implementing error boundaries, developers can deliver a stable and reliable application.

5. Advantages of Using React-error-boundary

React-error-boundary library is an ideal option for managing errors in the React application because it offers a wide range of benefits. Some of them are as mentioned below: 

  • Simplicity: You get a very simple, intuitive, and easy-to-use API with this library. It simplifies error management and offers appropriate suggestions to the developers. 
  • Function component friendly: Traditional error boundaries in the React needed to use class components but the react-error-boundary is built with function components. It leverages Hooks to align with modern React development practices
  • Versatility: This library is flexible and not opinionated. You can use the coding style and approach that suits your needs. 
  • Customizable fallback UI: When the error boundary catches an error, you can display the customizable fallback user interface. It helps prevent your React app from crashing and enhances the overall user experience. 

6. Limitations of React Error Boundaries

After seeing the benefits, it’s also important to take a look at the limitations of the error boundaries. Because the Error boundary can’t catch all errors. Some of those instances include: 

6.1 Event Handlers

Errors that occur in event handlers are not captured by error boundaries. The browser DOM manages them. So, the error boundary can’t catch the errors if they occur in the event handler. 

Further Reading on: How to Use React OnClick Event Handler?

6.2 Asynchronous Code

Similar to the event handlers, the error boundary can’t catch the errors in the asynchronous code too. React cannot recognize these errors, making it challenging to handle them effectively. 

6.3 Server-Side Rendering

Error boundaries are used specifically for the client side. So it won’t be able to detect errors on the server side. Server-side errors must be managed on the server and communicated to the client separately. 

Further Reading on: Server-side Rendering in React

6.4 Errors in the Error Boundary Component

The Error boundary component cannot handle the errors occurring in itself. So, be careful when crafting this component. The error boundaries help display the fallback user interface, they don’t manage the state of the errors themselves. So, you would need an error state management system and recovery strategies for your React application.  

7. Approaches to Implement Error Boundaries

There are various ways to implement error boundaries in your React application. This section discusses all the suitable ones. 

7.1 Component-Level Error Boundaries

Using this approach, you can wrap the React components with an error boundary. You can handle the errors with a high level of granularity for every component separately. The error boundary would detect the errors when they occur and prevent them from spreading across the component tree. 

The problem will be isolated to the crashed component while the remaining of the app will function seamlessly. Such an approach comes in handy when your app is made up of separate components. In such instances, the failure of a single component won’t affect the functionality or performance of the entire application. 

However, if every component would need its error boundary, it would result in a lot of duplication. 

7.2 Layout-Level Error Boundaries

If there is an error that affects an entire section of your React application like a dashboard or a sidebar then implementing layer-level error boundaries is the best option. This approach is used to wrap a group of related components that share a common state with an error boundary. It’s implemented a little higher on the component tree. 

When the error occurs in a single component of this group, the error boundary will display the error message on the fallback UI. This approach is less granular than the component-level design pattern. So, if there is an error in a single component, the entire group would crash even if other components are working properly. 

7.3 Top-Level Error Boundaries

It’s the design pattern that you execute at the top of the component tree. It’s an error-handling solution that can catch all types of errors occurring in your app. It ensures that your app remains secure and fully functional by catching and handling errors across your entire application. But it has the least granular approach. So sometimes a single error from a single component can affect your whole application.  

8. Conclusion

React error boundaries are very useful for handling errors in specific components. Although there are some limitations, a few additional features are available with the react-error-boundary package that can help you overcome these challenges. 

The react-error-boundary package is an ideal option for modular systems or projects that involve granular testing. It effectively manages the errors in React applications and helps deliver a better user experience even in the event of errors.

FAQs 

What is the error boundary in React?

Error boundary is a component specific to React. It is used to wrap the component tree and prevent errors from the components from affecting the entire application and resulting in a crash. This component is wrapped around the component or group of components you want to protect. 

What is the difference between errorElement and ErrorBoundary?

The basic difference between errorElement and errorBoundary is that the former component helps render specific UI for errors occurring during the rendering of a routed component or processing of the route’s actions functions or loaders, whereas the latter is used for unexpected errors. 

How do you handle errors in React?

Errors in React are handled using error boundaries which are wrapped around the component tree. The error boundary detects errors when they occur and displays the error message on the fallback UI. 

How do you handle error boundaries?

You just have to write the error boundary component once and then you can implement it anywhere across the application. Error boundaries work exactly like the JavaScript catch {} block but for components.

Comments


Your comment is awaiting moderation.