Weekly Webtips
Published in

Weekly Webtips

Handle React Errors with Error Boundaries

A simple guide to React Error Boundaries

In React, by default errors can propagate all the way up an application and break an entire app upon the next render. These issues were often caused by an earlier error in the application code but weren’t handled gracefully and cause the entire rendering cycle to start.

In React 16, the concept of “error boundaries” were introduced to address this issue. Error boundaries are React components that catch errors anywhere in their children, log the errors, and display a fallback UI instead of crashing the application.

Handle React Errors with Error Boundaries
Photo by Sigmund on Unsplash

Error boundaries can catch errors during rendering, lifecycle methods, and constructors of all the component tree below them. However, they don’t catch errors for Event handlers, asynchronous code, server-side rendering, and errors thrown in the Error boundary itself.

That being said, Error Boundaries are still great tools for writing more modular and resilient code.

Life Without Error Boundaries

Errors will almost always pop up in an application, it’s inevitable. Whether it’s trying to exist a deeply nested property on an undefined property or some 3rd party failure, errors are an inherent part of web development.

In this example, we’ll simulate an error to see how React handles it by default:

This example is from here by William Le on CodePen

Whenever the app encounters an error, the component will unmount itself and render a blank HTML page instead. This obviously is an unintuitive and undescriptive way to handle an error that will confuse users and provides no useful debugging information

This is where Error boundaries come in, handling these inevitable problems with grace.

With Error Boundaries

Error boundaries aren’t prebuilt components, but rather 2 lifecycle methods that React 16 introduced:

  • static getDerivedStateFromError is a lifecycle method that gives an Error boundary access to update the step and re-render the application.
  • componentDidCatch will trigger side effects when errors are thrown. This is helpful for logging tools or accessing the stack trace.

Let's take a look at these in action with an ErrorBoundary component we created:

Source

Here, we can see that both lifecycle hooks are in action: getDerivedStateFromError is used to display a fallback UI while componentDidCatch is used to log debug information to an external service.

This new ErrorBoundary component can wrap any other component, similar to a catch {} block, but for components rather than functions.

Error boundaries are only supported by class components, but thankfully these are incredibly reusable across an application.

We can fix our buggy example from before with this new ErrorBoundary

See Live Demo

Now, if you click the + button, you’ll end up with a graceful crash when the number reaches 5, the page will display a fallback UI that provides some visual feedback to the user.

Where to Place Error Boundaries

How granular or universal error boundaries should be is up to you. Top-level routes can be wrapped in Error Boundaries to display a generic message like “Something Went Wrong” to users at a bare minimum. Individual widgets can be wrapped to contain crashes from spreading through an entire application.

Error Boundaries v. Try Catch

Error boundaries and try-catch statements have two different purposes. Error boundaries intercept errors from three main sources:

  1. During the render phase
  2. In a lifecycle method
  3. In the constructor

This is anywhere where React is involved in a component. However, Error Boundaries won’t catch errors in these sections:

  1. Event handlers (i.e. onClick )
  2. setTimeout
  3. Server-Side Rendering (SSR)
  4. Any errors caused by the boundary itself

Try catch statements on the other hand are used for catching errors caused by logical issues within code, not to monitor component state for errors. These can be used to catch errors in event handlers and other places where Error Boundaries won’t work.

Conclusion

Error Boundaries are a great feature introduced in React v16 for writing more sustainable and resilient React code. It’s advisable to at least wrap your application root in an Error Boundary to display a descriptive error message or fallback UI if your application does fail.

Smaller components can also be wrapped in Error Boundaries, providing ways to prevent large-scale application failure from small problems propagating up.

Keep in Touch

There’s a lot of content out there and I appreciate you reading mine. I’m an undergraduate student at UC Berkeley in the MET program, a software developer at Carline, and a young entrepreneur. I write about software development, startups, and failure (something I’m quite adept at). You can signup for my newsletter here or check out what I’m working on at my website.

Feel free to reach out and connect with me on Linkedin or Twitter, I love hearing from people who read my articles :)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store