DEV Community

Siddharth Singh Bhadauriya
Siddharth Singh Bhadauriya

Posted on

Crashing gracefully while error handling using Error Boundaries.

Problem at Hand

Suppose a JavaScript error occurs within a component, it might cause React's internal state to be corrupted, resulting in cryptic errors. I ran into the same situation, just like you and many others too.
During the development of our apps, we will invariably run into unforeseen errors. It's possible that you're attempting to access a deeply nested property on an object that doesn't exist, or that it's out of your control (like a failed HTTP request to a third-party API).
Errors are bound to happen in our applications. When an issue occurs in the app, the component unmounts altogether, leaving the user with a blank HTML page. Users may become perplexed and unsure of what to do next as a result of this.

The Solution

As a result, a number of techniques have been created to prevent these problems from interfering with the user and developer experience. The use of error boundaries is one such way in React.
Error Boundaries give an elegant method to deal with these problems!


What exactly are Error Boundaries? It's not a new component or JavaScript library, contrary to popular belief. It’s more like a strategy for handling errors in React components.


Table of Contents

Installation

Installed as one of your project's dependencies:

npm install --save react-error-boundary
Enter fullscreen mode Exit fullscreen mode

Explanation

Reason to Use:
Error boundaries are React components which catch JavaScript errors anywhere in our app, log those errors, and display a fallback UI. It does not break the whole app component tree and only renders the fallback UI whenever an error occurred in a component.
We can use Error Boundaries to give the user visual notification that something went wrong while still allowing them to engage with our programme.
So now they have the option of navigating away or contacting customer service for assistance in resolving their issue! It's a terrific technique to make up for an otherwise bad user experience.

Working Principle
Error boundaries catch errors during rendering in component lifecycle methods, and constructors of the whole tree below them. So basically, error boundaries only handle errors in the parts of our code that involve React.
Suppose an error is encountered then what happens is as soon as there is a broken JavaScript part in Rendering or Lifecycle Methods, It tries to find the nearest Error Boundaries Tag and sort the error out with a Fallback-UI.

Usage

The simplest way to use <ErrorBoundary> is to wrap it around any component that may throw an error. This will handle errors thrown by that component andits descendants too.

import {ErrorBoundary} from 'react-error-boundary'

function ErrorFallback({error, resetErrorBoundary}) {
  return (
    <div role="alert">
      <p>Something went wrong:</p>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  )
}

const ui = (
  <ErrorBoundary
    FallbackComponent={ErrorFallback}
    onReset={() => {
      // reset the state of your app so the error doesn't happen again
      //eg. reload the page using window.location.reload()
    }}
  >
    <ComponentThatMayError />
  </ErrorBoundary>
)
Enter fullscreen mode Exit fullscreen mode

You can react to errors (e.g. for logging) by providing an onError callback:

import {ErrorBoundary} from 'react-error-boundary'

const myErrorHandler = (error: Error, info: {componentStack: string}) => {
  // Do something with the error
  // E.g. log to an error logging client here
}

const ui = (
  <ErrorBoundary FallbackComponent={ErrorFallback} onError={myErrorHandler}>
    <ComponentThatMayError />
  </ErrorBoundary>,
)
Enter fullscreen mode Exit fullscreen mode

Comparison with TryCatch

One question that may cross your mind is why should you learn this new concept when Error Boundaries works like Catch? Well, the answer is Try…catch is used in specific code blocks where you program the functionality of the application.

Try…Catch deals with imperative code while Error Boundaries deal with declarative code and as we know that React is declarative in nature, and Error Boundaries help in preserving the declarative nature of React.

Imperative programming is how you do something and declarative programming is what you do.

With error boundary, if there is an error, you can trigger a fallback UI; whereas, with try…catch, you can catch errors in your code and throw/re-throw/handle the error and further display it using a modal bla bla...

Error Boundaries actually aren’t in direct competition with try...catch statements as Error Boundaries are only designed for intercepting errors that originate from 3 places in a React component: During render phase, In a lifecycle method, In the constructor (Reacty Stuffs).

Limitations

There are certain limitations to Error Boundaries too.
Following are the places where Error Boundaries will not be able to catch an error:

  • Event handlers (e.g., onClick, onChange, etc.).
  • Asynchronous code(Example request Animation Frame, setTimeout)
  • Server-side rendering (SSR)
  • And errors caused by the error boundary itself (rather than its children)

So Error Boundaries don’t really impact how you use try...catch. They’re both needed as a robust strategy for handling errors in React.


I recently came across this concept and was not able to stop myself falling in love with such component-based-js-errors-catching.
I hope this helps

Top comments (0)