Error thrown from child component in componentDidMount lifecycle method is not caught in error boundary

橙三吉。 提交于 2021-01-29 02:41:54

问题


I am learning React and am unable to get an Error Boundary catching a network connection error thrown by an axios http request in a child component when the API server is unavailable.

I can see that the error is logged in the catch handler of the child component, however the throw statement is not caught by the ErrorBoundary component.

Any ideas how to get the Error Boundary catching an error thrown from componentDidMount lifecycle method?

Parent - App.tsx

export class App extends React.Component<AppProps, {}> {
  public render(): JSX.Element {
    return (
      <div>
        <ErrorBoundary>
          <AppBar color="primary" position="static">
            <Toolbar>
              <TypoGraphy variant="h6" color="inherit">
                Course App
              </TypoGraphy>
              <NavBar />
            </Toolbar>
          </AppBar>
          <CourseList />
        </ErrorBoundary>
      </div>
    );
  }
}

Child - CourseList.tsx

  componentDidMount(): void {
    console.log('CourseList::componentDidMount');

    const dataSource: RestDataCourse = new RestDataCourse();
    dataSource
      .getCourses()
      .then(courseList => {
        this.setState({ courses: courseList });
      })
      .catch(error => {
        console.error(`Error retrieving courses => ${JSON.stringify(error)}`);
        throw error;
      });
  }

ErrorBoundary

import * as React from 'react';

interface ErrorBoundaryProps {
  hasError: boolean;
  error: Error;
  info: React.ErrorInfo;
}
export default class ErrorBoundary extends React.Component<
  {},
  ErrorBoundaryProps
> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false, error: undefined, info: undefined };
  }

  componentDidCatch(error: any, info: any): void {
    console.log('ErrorBoundary has encountered an error');
    this.setState({ hasError: true, error: error, info: info });
  }

  render(): {} {
    if (this.state.hasError) {
      return (
        <div id="errorModal" className="modal">
          <div className="modal-content">
            <span className="close">&times;</span>
            <h2>Application Crash</h2>
            <p>Error encountered in application.</p>
            {this.state.error}
          </div>
        </div>
      );
    }

    // Render children if no error
    return this.props.children;
  }
}

回答1:


Error boundaries are designed to catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

If you want to catch unhandled promise errors globally (instead of handling it directly in component), you can use window.onunhandledrejection.

window.onunhandledrejection = function(e) {
  console.log(e.reason);
}

but it's not supported in all browsers by default.

Little hacky solution would be to call this.setState(() => { throw err; }); in catch of your promise.



来源:https://stackoverflow.com/questions/58267208/error-thrown-from-child-component-in-componentdidmount-lifecycle-method-is-not-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!