Resilient Architecture in React: Using Error Boundaries
Tags: react, frontend, webdev, beginners
Published: 2023-10-29 15:42:47

Recently I was implementing a pdf reader for a magazine on a page, I tested it on the desktop browser and everything worked perfectly.

The problem occurred on mobile, because after going through a few pages of the pdf, the site crashed completely: "Application error: a client-side exception has occurred (see the browser console for more information).".

![Console error img](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/511kfx2s891hkiqejaqz.png)

## Content summary
<ul>
    <li>
        <a href="#errorboundaries">What is Error Boundaries?</a>
    </li>
    <li>
        <a href="#quandousar">When to use and when not to use</a>
    </li>
    <li>
        <a href="#Opcionais">Optionals</a>
    </li>
    <li>
        <a href="#terceiros">Third-party libraries</a>
    </li>
</ul>

<b><b>

I'm not going to talk about the solution, but about how to prevent your application crashing completely in these cases, using the concept of Error Boundary to present an alternative UI in the case of an error.

<div style="display: flex; justify-content: space-between;">
<figure style="width: 48%; margin-right: 2%;"> 
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f3t7n1qo9vmf2rhkhm3n.png" alt="Error screen not handled" style="width: 48%; margin-right: 2%;"/>

  <figcaption>Error screen not handled</figcaption>
</figure>

<figure style="width: 48%;"> 
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9s46vqz2v6d94di7yxwz.png" alt="UI with error boundary handling" style="width: 48%;"/>

  <figcaption>UI with error boundary handling</figcaption>
</figure>
</div>

Before React 16, an error in any component could result in the entire application crashing, as the error was propagated (intentionally, it's not a bug, it's a feature🫣), completely breaking the site and creating a bad user experience. With the arrival of React 16, Error Boundaries were introduced, allowing developers to capture and handle errors in specific components, without bringing down the entire application.

**What are Error Boundaries?** <a id="errorboundaries" href="#errorboundaries">&#128279;</a>

Error Boundaries is a React component that catches JavaScript errors in its child components, logs those errors and displays a fallback interface instead of the failed component, working like a *catch{} for components.

Currently, it's only available as a class component and, so far, there's no evidence of the React team wanting to change this (ok, officially there isn't, but you'll find ways to do this both manually and with external libs and I'll talk about that later).

**Code Example**:

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

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    logErrorToService(error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something has gone wrong.</h1>;
    }
    return this.props.children;
  }
}

```

Let's better understand the role of the functions:

- **getDerivedStateFromError**: This static function is used to update the local state of the component and render a fallback UI after an error.
- **componentDidCatch**: This method is triggered after an error is caught by the Error Boundary. It is useful for logging errors or side effects.

When using Error Boundary in your application, wrap the components you want to protect:

```jsx
<ErrorBoundary>
  <Component />
</ErrorBoundary>
```

You can also involve the entire application or you can involve the content of the site excluding the layout or even just routes, it all depends on the design you choose and which makes the most sense in your context.

**When to use and when not to use** <a id="quandousar" href="#quandousar">&#128279;</a>

**When to use**

- In non-critical components or functionalities.
- When incorporating widgets or third-party libraries.

**When not to use**
- For expected errors (such as known API errors).
- Within event handlers.
- For errors that should be handled specifically and not generically.
- Asynchronous code: Error Boundaries do not catch errors in asynchronous operations outside of React components, such as `setTimeout` or `requestAnimationFrame`. To handle errors in asynchronous operations inside components, you must use `try/catch` blocks.
- Server-side rendering
- Errors thrown in the Error Boundary itself.

**Optionals:** <a id="opcionais" href="#opcionais">&#128279;</a>
- Integrate Error Boundaries with error monitoring solutions for quick identification and correction, you can integrate with Sentry or Exceptionless for example.
- Test your Error Boundaries to ensure that they work as expected in different scenarios.

**Third-party libraries**: `react-error-boundary` <a id="terceiros" href="#terceiros">&#128279;</a>
While React's native Error Boundaries are sufficient to handle these needs, some third-party libraries have been developed to simplify and enrich this functionality. One of the most popular is `react-error-boundary`.

**Main benefits**

**Simplified API**: With `react-error-boundary`, you can create an error boundary with a simple fallback function, without the need to create a component class, and it offers several other possibilities, which I won't go into today.

example with `react-error-boundary`:


```jsx


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

function FallbackComponent({ error }) {
  return <div>An error has occurred: {error.message}</div>
}

<ErrorBoundary FallbackComponent={FallbackComponent}>
  <Component />
</ErrorBoundary>

```

**Additional Hooks and Utilities**: The library offers the `useErrorHandler` hook, which allows you to catch and handle errors within functional components and custom functions.

**Automatic Restart**: With the `onReset` property, you can define how the component should restart itself after an error.