"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Mastering Error Boundaries in React: A Guide to Effective Error Handling

Mastering Error Boundaries in React: A Guide to Effective Error Handling

Published on 2024-08-05
Browse:904

Mastering Error Boundaries in React: A Guide to Effective Error Handling

What is an Error Boundary?

While building applications, errors are inevitable. They might come from APIs, UI or from several other places.

It's very important to handle these errors gracefully & maintain good UX despite these errors.

Error Boundary is one such way of error handling in React.


How does Error Boundary help?

To understand this, let's understand the situation before the introduction of the Error Boundary.

Before Error Boundaries, the errors occurring inside components eventually propagated & broke the UI or rendered the white screen.

This caused a really bad UX.

Error Boundary helps us to handle such errors & display a fallback UI instead of breaking the UI or white screen displayed.


How to use Error Boundary?

React v16 officially introduced Error Boundary.

It's a Class-Based Component which can be used to wrap your application.

It accepts a fallback UI to be displayed in case your application has errors or otherwise, it simply renders the children component to resume the normal flow of your application.

This is how the React Documentation recommends using it,

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

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Example "componentStack":
    //   in ComponentThatThrows (created by App)
    //   in ErrorBoundary (created by App)
    //   in div (created by App)
    //   in App
    logErrorToMyService(error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return this.props.fallback;
    }

    return this.props.children;
  }
}


What's the problem with React's Error Boundary?

It cannot catch errors occurring in,

  • Event Handlers (these errors need to be handled with try-catch blocks)
  • Asynchronous Code (APIs, setTimeout, requestAnimationFrame etc.)
  • Server-side rendering
  • The error that occurs in Error Boundary itself
  • It does not work with Functional Components. Although we can make it work with a few code changes.
  • Hooks cannot be used inside it.

What's the solution?

There's a npm package called react-error-boundary which is a wrapper on top of the traditional Error Boundary component.

Using this package, we're able to overcome all the issues faced in the traditional Error Boundary component.


How to use it?

You can wrap your entire application with or you can wrap individual components with .

The granularity of implementation is up to you.

Let's understand how to use it.

import React from 'react';
import { ErrorBoundary } from "react-error-boundary";

const App = () => {
return Something went wrong}>
/* rest of your component */

}

This is the simplest example of using ErrorBoundary. There's more to this library.


Understanding react-error-boundary API

Let's try to understand API with different scenarios.

1. I want to show a generic fallback UI for Errors in the Application

 import React from 'react';
 import { ErrorBoundary } from "react-error-boundary";

 const App = () => {
 return Something went wrong}>
 /* rest of your component */
 
 }

2. I want to show specific error details in my fallback component

 import React from 'react';
 import { ErrorBoundary } from "react-error-boundary";

 function fallbackRender({ error, resetErrorBoundary }) {
   // Call resetErrorBoundary() to reset the error boundary and retry the render.
   return (
     

Something went wrong:

{error.message}
); } const App = () => { return { // Reset the state of your app so the error doesn't happen again }} > /* rest of your component */ }
); } const App = () => { return { // Reset the state of your app so the error doesn't happen again }} > /* rest of your component */ }

Instead of fallback or fallbackRender, you can also use a React Component.

 import React from 'react';
 import { ErrorBoundary } from "react-error-boundary";

 const Fallback = ({ error, resetErrorBoundary }) => {
   // Call resetErrorBoundary() to reset the error boundary and retry the render.
   return (
     

Something went wrong:

{error.message}
); } const App = () => { return { // Reset the state of your app so the error doesn't happen again }} > /* rest of your component */ }
); } const App = () => { return { // Reset the state of your app so the error doesn't happen again }} > /* rest of your component */ }

3. I want to Log my errors

 import React from 'react';
 import { ErrorBoundary } from "react-error-boundary";

 const logError = (error: Error, info: { componentStack: string }) => {
   // Do something with the error, e.g. log to an external API
 };

 const Fallback = ({ error, resetErrorBoundary }) => {
   // Call resetErrorBoundary() to reset the error boundary and retry the render.
   return (
     

Something went wrong:

{error.message}
); } // You can use fallback / fallbackRender / FallbackComponent anything const App = () => { return { // Reset the state of your app so the error doesn't happen again }} > /* rest of your component */ }
); } // You can use fallback / fallbackRender / FallbackComponent anything const App = () => { return { // Reset the state of your app so the error doesn't happen again }} > /* rest of your component */ }

4. I want to catch errors in event handlers & async code

 import { useErrorBoundary } from "react-error-boundary";

 function Example() {
   const { showBoundary } = useErrorBoundary();
   const getGreeting = async(name) => {
     try {
         const response = await fetchGreeting(name);
         // rest of your code
     } catch(error){
          // Show error boundary
         showBoundary(error);
     }
   }
   useEffect(() => {
    getGreeting()
   });

   return 
 }


A few gotchas

ErrorBoundary is a client component. You can only pass props to it that are serializeable or use it in files that have a "use client"; directive.

1. What is a serializable prop?

Serilzable prop means it can be converted to byte stream in such a way that byte stream can be converted back to orignal prop.

A common way to do that in Javascript is JSON.stringify() & JSON.parse().

2. How to use "use client"; directive?

Simply mention it at top of the file

"use client";


There are a few more variations you can use. But this article is good enough to get you started.

Checkout their full documentation here.

Please let me know in the comments if you found it helpful.

Happy Coding!

Release Statement This article is reproduced at: https://dev.to/dev_diaries_by_varun/mastering-error-boundaries-in-react-a-guide-to-effective-error-handling-48g3?1 If there is any infringement, please contact [email protected] delete
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3