Today rtolzo Learned
Github
Tags
Github
Tags
  • Topics
    • Typescript
    • Git
  • TIL
    • 2022 TIL
    • 2023 TIL
    • 2024 TIL

React ErrorBoundary에서 fetch 에러를 catch 하지 못하는 이유

React에서는 class component의 getDerivedStateFromError 메소드로 컴포넌트에서 throw하는 에러를 catch할 수 있다.

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

  static getDerivedStateFromError(error) {
    // 다음 렌더링에서 폴백 UI가 보이도록 상태를 업데이트 합니다.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 에러 리포팅 서비스에 에러를 기록할 수도 있습니다.
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 폴백 UI를 커스텀하여 렌더링할 수 있습니다.
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

하지만 fetch에서 throw 하는 에러는 catch하지 못하는데 그 이유는 바로 실행 컨텍스트가 다르기 때문이다. React는 동일한 실행컨텍스트 내에서 발생하는 에러만 핸들링 할 수 있다. fetch가 실행되는 시점은 V8 엔진의 콜스택이지만, 비동기적으로 Web API에서 별도의 실행 컨텍스트에서 실행되고, 이 Web API는 C++ 등의 네이티브 언어로 개발 되었기에 여기서 말하는 실행 컨텍스트는 C++의 실행컨텍스트이다. 즉, 브라우저에 console에 출력되는 fetch 에러 메세지도 C++에서 출력된 것 이므로 V8 엔진 실행컨텍스트에서 C++ 실행컨텍스트에서 발생한 에러를 catch 할 방법은 없기에 ErrorBoundary가 catch 할 수 없다.

이를 해결하기 위해선 비동기 작업이 끝난 이후 응답에 따라 Javascript 실행 컨텍스트 내에서 throw 해주면 ErrorBoundary가 catch 할 수 있다.

마지막 수정일: