Error Handling in React 16

React 16 introduces bunch of features, most interesting one is “error boundary”. In this article, we will see what is error boundary, and how to log errors from error boundary to Atatus.

What are exactly error boundaries?

In the past, any JavaScript errors inside React components used to corrupt React’s internal state and cause it to emit cryptic errors on next renders. These errors were always caused by an earlier error in the application code, but React did not provide a way to handle them gracefully in components, and could not recover from them. Also, JavaScript error in a part of the UI shouldn’t break the whole app. To solve this problem, React 16 introduces a new concept of an error boundary.

Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI to replace the component tree that has crashed. They are similar to try-catch statements in your code, but surround page elements instead.

An error boundary is a React component with a componentDidCatch(err, info) method. Any errors occurring in a component tree get reported up to the nearest error boundary’s componentDidCatch function. Note that error boundaries only catch errors in the components below them in the tree. For simple apps, you can declare an error boundary component once and use it for your whole application. For more complex applications with multiple components, you can have independent error boundaries to gracefully recover each part.

You can also report these errors to an error monitoring service like Atatus. This will give you the ability to track how many users are affected by errors, find what caused them, and ultimately improve your user experience.

How to implement React error boundaries?

Below is a basic component with error boundary. The componentDidCatch method allows you to catch the error, and change how the component is rendered. For example, you can display an error message like “Something went wrong!” and also send the error to Atatus.

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

  componentDidCatch(error, errorInfo) {
    // Display fallback UI
    this.setState({ hasError: true });
    atatus.notify(error); // Send it to Atatus!
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

Add your new component in HTML, surrounding the parts you would like to include in your error boundary. In this example, we are adding an error boundary around a buggy widget component.

<ErrorBoundary>
  <BuggyWidget />
</ErrorBoundary>

The componentDidCatch() method works like a JavaScript catch {} block, but for components. Only class components can be error boundaries. In practice, most of the time you’ll want to declare an error boundary component once and use it throughout your application.

Note that error boundaries only catch errors in the components below them in the tree. An error boundary can’t catch an error within itself. If an error boundary fails trying to render the error message, the error will propagate to the closest error boundary above it. This, too, is similar to how catch {} block works in JavaScript.


Monitor React App Performance and Errors with free 14 day trial – no credit card required. Questions? - get in touch with us.

Atatus

#1 Solution for Logs, Traces & Metrics

tick-logo APM

tick-logo Kubernetes

tick-logo Logs

tick-logo Synthetics

tick-logo RUM

tick-logo Serverless

tick-logo Security

tick-logo More

Fizer Khan

Fizer Khan

Co-Founder & Architect at Atatus
Chennai