javascriptreactjsreact-hooksreact-error-boundary

React Error Boundaries not working with React


This is my Error Boundary file -

class ErrorHandling extends Component {
    state = { hasError: false }

    componentDidCatch() {
        this.setState({ hasError: true })
    }

    render() {
        // debugger
        if (this.state.hasError) {
            return <div>Error in Component</div>
        }
        return this.props.children
    }
}

And the other file is -

import React, { Component } from 'react';

// Intentionally I have added syntax error below 'd'

function Intermediate(props) {
    return <h1>hi</h1>;d
}
export default Intermediate

And in my App.js

<ErrorHandling>
  <Intermediate />
</ErrorHandling>

It is causing the application to break without catching the error. Here is the error is seen on the browser screen

enter image description here

The more detailed version here- https://codepen.io/meghana1991/pen/abojydj?editors=0010

When I use the same code in my local with multiple files as above listed, it doesn't work


Solution

  • You can't catch compile-time errors, the Error Boundaries are for run-time errors within the UI.

    Refer to Compile time vs run time errors.

    Moreover, you have to use getDerivedStateFromError in order to add additional render on fall back UI:

    class ErrorBoundary extends React.Component {
      state = {
        hasError: false,
        error: { message: '', stack: '' },
        info: { componentStack: '' }
      };
    
      static getDerivedStateFromError = error => {
        return { hasError: true };
      };
    
      componentDidCatch = (error, info) => {
        this.setState({ error, info });
      };
    
      render() {
        const { hasError, error, info } = this.state;
        const { children } = this.props;
    
        return hasError ? <ErrorComponent/> : children;
      }
    }
    

    For checking your ErrorBoundary, throw an error from a reachable section in the component tree which is not:

    const ButtonComponent = () => {
      throw Error("error!");
      return <></>;
    };
    

    Note: In development env you will always see the error overlay unless you turn it off or close it with the X button.


    Full example:

    const ErrorComponent = () => {
      return <h1>Something went wrong</h1>;
    };
    
    class ErrorBoundary extends React.Component {
      state = {
        hasError: false,
        error: { message: "", stack: "" },
        info: { componentStack: "" }
      };
    
      static getDerivedStateFromError = error => {
        return { hasError: true };
      };
    
      componentDidCatch = (error, info) => {
        this.setState({ error, info });
      };
    
      render() {
        const { hasError, error, info } = this.state;
        console.log(error, info);
        const { children } = this.props;
    
        return hasError ? <ErrorComponent /> : children;
      }
    }
    
    const ButtonComponent = () => {
      throw Error("error!");
      return <></>;
    };
    
    const App = () => {
      return (
        <ErrorBoundary>
          <ButtonComponent />
        </ErrorBoundary>
      );
    };
    

    Edit Error-Boundary Example