Error-Boundary 라이브러리를 사용하여 Error Boundary구현하기

ijimlnosk·2024년 3월 30일
0
post-thumbnail
post-custom-banner

💪 Error Boundary란?

  • 하위 컴포넌트 트리의 어디에서든 자바스크립트 에러를 기록하며 깨진 컴포넌트 트리 대신 fallback UI를 보여주는 React 컴포넌트 이다.
  • 생명주기 메서드인 static getDerivedStateFromError()componentDidCatch() 중 하나(혹은 둘 다)를 정의하면 클래스 컴포넌트 자체가 error boundary가 된다.
    • 에러 발생 후 fallback UI 를 렌더링하려면 static getDerivedStateFromError()를 사용
    • 에러 정보를 기록하려면 componentDidCatch()를 사용

error boundary는 다음과 같은 에러는 포착하지 않는다

  • 이벤트 핸들러
  • 비동기적 코드 ( 예: setTimeout 혹은 requestAnimationFrame 콜백 )
  • 서버 사이드 렌더링
  • 자식에서가 아닌 error boundary 자체에서 발생하는 에러

자세한 내용은 참고한 링크에서 볼 수 있다.

💪 Error-Boundary 라이브러리

알아본 결과 error boundary를 작성할 때 함수형으로 작성할 방법이 없다고 한다.
그래서 클래스 형태로 작성하게 되는데 error-boundary라이브러리를 사용하면 error boundary를 따로 구현하지 않고 사용할 수 있다.

💪 설치 방법

npm install react-error-boundary

간단한 예제로 사용해봤다

// errorFallback.jsx
const ErrorFallBack = ({ error, resetErrorBoundary }) => {
    let errorMsg = "예기치 못한 에러가 발생했습니다.";

    switch (error.status) {
        case 401:
            errorMsg = "인증되지 않은 사용자입니다.";
        case 404:
            errorMsg = "요청한 페이지를 찾을 수 없습니다.";
        case 500:
            errorMsg = "서버에서 에러가 발생했습니다.";
    }

    return (
        <div>
            <p>{errorMsg}</p>
            <p> 상세 : {error.message}</p>
            <button onClick={() => resetErrorBoundary()}>재시도</button>
        </div>
    );
};
export default ErrorFallBack;
//errorComponent
// 에러가 발생한 컴포넌트
const ErrorComponent = ({ error }) => {
    const err = new Error();
    err.message = "에러 발생 컴포넌트";
    err.status = error;
    throw err;
};
export default ErrorComponent;

간단하게 3가지의 에러사항만 설정해주었다.

💪 사용해보기

테스트해보기 위해 전에 간단하게 만들어본 페이지를 배포시켜서 사용을 해보았다.
배포한 이유는 빌드 파일로 확인을 해줘야 하기 때문이였는데
React 개발 모드에서는 React 자체의 에러 오버레이가 에러를 잡을 수 있다고 해서 설정해준 error fallback이 제대로 나오지 않아서 그렇다.

error fallback을 만들어주고

// errorFallBack.js
const ErrorFallBack = ({ error, resetErrorBoundary }) => {
    return (
        <div role="alert">
            <p>에러가 발생했습니다</p>
            <pre>{error.message}</pre>
            <button onClick={resetErrorBoundary}>재시도</button>
        </div>
    );
};
export default ErrorFallBack;

라우터에서 사용을 해주었다.

RouterProvider 사용 시 Error Boundary

원래는 App.js에서 사용을 해줬는데 제대로 동작하지 않았다
그 이유로는 RouterProvider와 관련된 에러 처리의 특성 때문일 수 있다고 한다.
App.js에서 전역적으로 ErrorBoundary를 사용하면,
이는 RouterProvider 밖에 있기 때문에, RouterProvider 내부 라우트에서 발생한 에러를 잡을 수 없다.
ErrorBoundary는 자신의 자식 컴포넌트 트리에서 발생한 에러만 캐치할 수 있으며,
RouterProvider가 내부적으로 관리하는 컴포넌트 트리는 그 범위에 포함되지 않는다.

// route.js
const router = createBrowserRouter([
    {
        path: '/',
        element: <RootLayout />,
        children: [
            {
                path: '',
                element: (
                    <div style={{ paddingTop: '100px' }}>
                        <ErrorBoundary FallbackComponent={ErrorFallBack}>
                            <MainPage
                                queryKey={['popularData']}
                                dataApi={popularApi}
                            />
                        </ErrorBoundary>
                    </div>
                ),
            },

그리고 일부러 에러를 발생시켜 테스트를 진행해봤다
처음에는 useEffect를 사용하여 페이지가 마운트 되었을 때,
에러처리를 해주었는데 제대로 동작하지 않아 찾아보니
ReactuseEffect함수 내부에서 발생하는 에러는 비동기적으로 처리되기 때문에, ErrorBoundary가 잡아내지 못하고, 대신 React 내부의 전역 에러 핸들러가 처리를 한다고 한다.

throw new Error('test error');

그래서 이렇게 동기적으로 에러처리를 해주었다.

  • 결과

    결과적으로 이렇게 에러가 발생되는 것을 확인하였다

추후 다른 토이프로젝트 및 프로젝트 진행 시 좀 더 다양하고 자세하게 사용하기 위해 조금 더 알아봐야겠다.

post-custom-banner

0개의 댓글