React Error Boundaries

Learn via video courses

Overview

Error Boundaries in react are the class-based component that catches javascript errors thrown by their child components, logs the caught error, and displays a fallback UI. It does not break the whole component tree and only renders the fallback UI whenever any javascript error occurs. Error boundary catches the error during rendering, in lifecycle methods, and in constructors of the whole tree below the Error boundary component.

Introduction

Error boundary in react was introduced in React 16 to handle javascript errors occurring in the component tree. Error boundary catch errors during component rendering, in lifecycle methods, and constructors of the child component under the Error boundary component. According to React documentation, Error boundary do not catch error in

  • Event Handlers
  • Asynchronous code(e.g. setTimeout or requestAnimationFrame callbacks)
  • Server Side Rendering
  • Error is thrown in the Error Boundary itself

To create an Error Boundary we have to create a class component that will have a state variable hasError which determines whether or not the error boundary react has caught an error or not. The error boundary class component should also have at least three methods :

  • getDerivedStateFromError: This will be a static method that is used to update the error boundary state i.e hasError state variable.
  • componentDidCatch: This method is used to log an Error when an error is caught. The error can be also logged to an error reporting service.
  • render: This method is used to render the fallback UI when an error occurs.

Then you can use this ErrorBoundary Component to wrap the error-causing components under it.

Reason to Use

Error boundaries in React are used to catch errors in the components prone to producing errors. just as the catch{} block catches errors in javascript, similarly the error boundary does this for components in react.

In practice, most of the time we declare an Error boundary component once and use it wherever required in our application.

Working Principle

react-error-boundary npm package provides a reusable wrapper (<ErrorBoundary></ErrorBoundary>) that you can be used to wrap around your components instead of building the whole ErrorBoundary Component from scratch.

For using Error boundaries in react we have to simply wrap our component which is expected to produce an error with the ErrorBoundary component and we can also pass some extra prop to our ErrorBoundary component to customize the behavior of Error boundary in react.

Let's take an example and try to understand the working principle of React Error boundary.

Output:

Working Principle of error boundaries in react

In the above example, we have created two components ErrorCausingComponent1 and ErrorCausingComponent2 that are wrapped with the ErrorBoundary component to catch any error. We are passing a FallbackComponent prop to our ErrorBoundary Component to render a fallback component if any error occurs in the ErrorCausingComponent1 and ErrorCausingComponent2 in our App.

Where To Place Error Boundaries

It depends on you where you want to place the Error boundary in react. You can wrap the top-level route component to display the error message or "Something went wrong" message or you can wrap the individual component with an error boundary to handle the error in the component.

Error boundaries Do Not Catch Errors For The Following Events

Event Handlers

Error boundaries in reacting do not catch errors inside any event handler function.

There is no need for an error boundary to catch errors in event handlers as event handlers do not happen while rendering. The render method and lifecycle method happen during rendering so require an error boundary to catch errors and display a fallback UI.

In the case of an event handler, a simple try catch block will do the error handling in the event handler method.

The above example shows the use of a try-catch block to handle errors in event handlers.

Asynchronous Code(Example Request Animation Frame etc)

Most of the components fetch data asynchronously so if the component wrapped under an Error boundary throws any error then it cannot be handled by error boundaries in react.

As asynchronous code runs outside the render and commits phase of react so error boundaries are not able to handle the error thrown from asynchronous code.

Server-Side Rendering

The error boundary in reacts can only handle errors when the rendering takes place on the client side but not when there is server-side rendering.

Error Is Thrown In The Error Boundary Itself

Error boundaries in reacting can only catch errors in the components wrapped under the ErrorBoundary component. If the error boundary fails to render the error message then the error will propagate to the closest error boundary above it.

New Behavior for Uncaught Errors

Some errors are not caught by error boundaries in react, so what would happen if such an error occurs in our application? As of React 16, errors that are not caught by any error boundary will result in unmounting of the whole React component tree.

If there is an error in a payment processing app then it will be worse to show the wrong amount than to show nothing to the user.

As you migrate to React 16, you will be able to see more error crashes that were unnoticed earlier. Adding an Error boundary provides a better user experience when the UI crashes due to some reason.

Component Stack Traces

React 16 prints all the errors in the console even if the errors are not visible on the screen. In addition to printing, the error in the console React also provides component stack traces i.e you will be able to see exactly the component tree where the error occurred.

The component stack traces will look like the image shown below depending on the component you are handling the error for.

Component Stack Traces

You can also see the file name and the line number in the component tree where the error occurred. This helps in debugging the error more quickly. This works by default in create-react-app projects. If not using create react app then the plugin can also be added manually in the

Component Stack Traces 2

How About Try/Catch?

try/catch is not a good solution in the case of an error in react component tree. try/catch is good for imperative code i.e where functions are explicitly code to solve any problem.

React component code is declarative which specifies what should be rendered.

Error boundary in reacts preserves the declarative nature of reacting code and if any error occurs in the component tree rendering then the error boundary catches the error and renders a fallback UI.

How About Event Handlers?

As event handlers do not happen on rendering so error boundaries in react are not able to catch any error which occurs while event handlers are invoked.

If you want to catch the error occurring in event handlers then try/catch will be the best possible way to handle errors in event handlers.

Conclusion

  • Error boundaries in reacting are always a class-based component.
  • Error boundary in react is used to catch javascript error occurring in the child components wrapped around the error boundary component.
  • Error boundary catches the error, logs the error, and also displays the fallback UI preventing the breaking of the component tree.
  • Error boundary cannot catch errors in the event handler, Asyncronus code, server-side rendering, or error occurring in its component.
  • Error boundaries can be placed at the top level of the app wrapping all the components or they can also be wrapped around individual components.