Next.js 13 - 1. Routing - 1.6. Error Handling

Chaewon Kang·2023년 4월 25일
4

Error Handling (에러 핸들링)

error.js 파일 컨벤션은 중첩된 루트들 안에서 우아하게 런타임 에러를 핸들링할 수 있게 도와줍니다.

  • 루트 세그먼트와 루트 세그먼트의 중첩된 자식 요소들을 리액트 에러 바운더리 안에서 자동으로 감싸줍니다.
  • granular한 상태에 알맞게 적용되기 위해, 파일 시스템의 위계를 사용하여 특정한 세그먼트들에 알맞게 가공된 에러 UI를 생성합니다.
  • 애플리케이션의 나머지 부분들이 잘 작동하도록 유지하면서, 영향을 받은 세그먼트의 에러들을 분리시킵니다
  • 전체 페이지를 리로드하지 않고 에러로부터 벗어날 수 있는 시도를 위한 기능을 추가합니다

루트 세그먼트 안에 error.js파일을 추가하여 에러 UI를 생성하고, 리액트 컴포넌트를 익스포트하세요:

// app/dashboard/error.tsx

'use client'; // 에러 컴포넌트는 반드시 클라이언트 컴포넌트여야 합니다

import { useEffect } from 'react';

export default function Error({
	error,
    reset,
}: {
	error: Error,
    reset: () => void;
}) {
	useEffect(() => {
    	// 에러 리포트 서비스에 에러를 기록합니다
        console.error(error);
    }, [error]);
    
    return (
    	<div>
        	<h2>Something went wrong!</h2>
            <button
            	onClick={
                	// 세그먼트를 리렌더링하여 에러로부터 리커버링을 시도합니다
                    () => reset()
                }
            >
            	Try again
            </button>
        </div>
    );
}

How error.js Works (error.js는 어떻게 동작할까요)

  • error.js는 자동으로 리액트 에러 바운더리를 생성하고, page.js 컴포넌트 또는 중첩된 자식 세그먼트를 감쌉니다.
  • error.js파일로부터 익스포트된 리액트 컴포넌트는 폴백 컴포넌트로 사용됩니다.
  • 에러 바운더리 안에서 에러가 발생하면, 해당 에러가 포함 되며, 폴백 컴포넌트가 렌더 됩니다.
  • 폴백 에러 컴포넌트가 활성화되어 있을 때, 에러 바운더리 상위의 레이아웃들은 그들의 상태를 유지하며, 인터랙티브한 상태를 지속합니다. 그리고 에러 컴포넌트는 에러로부터 리커버링될 수 있도록, 기능성(functionality)을 디스플레이할 수 있습니다.

Recovering From Errors (에러 회복하기)

에러의 원인은 종종 일시적일 수 있습니다. 이러한 경우에는 간단하게 다시 시도하는 것을 통해 문제를 해결할 수 있습니다.

에러 컴포넌트는 유저가 에러를 회복하기 위한 시도를 할 수 있도록reset() 함수를 사용할 수 있습니다. 이 함수가 실행되면, 함수는 에러 바운더리의 컨텐츠를 리렌더링 하려는 시도를 할 것입니다. 만약 성공한다면, 폴백 에러 컴포넌트는 리렌더링 결과물로 대치될 것입니다.

// 'use client';

export default function Error({
	error,
    reset,
 }: {
 	error: Error;
    reset: () => void;
}) {
	return (
    	<div>
        	<h2>Something went wrong!</h2>
            <button onClick={() => reset()}>Try again</button>
        </div>
    );
}

Nested Routes (중첩 루트)

특별한 파일들 (special files)를 통해 생성된 리액트 컴포넌트들은 특정한 중첩 위계 안에서 렌더링 됩니다.

예를 들어, 둘 다 각각의 layout.jserror.js를 포함하고 있는, 한 중첩 루트 안의 두 세그먼트 파일들은 아래의 간소화된 컴포넌트 위계에 따라 렌더됩니다:

중첩된 컴포넌트 위계는 중첩된 루트 전반에 걸쳐 error.js 파일의 행동 양식에 아래와 같은 함의들을 갖습니다:

  • 에러는 가장 가까운 부모 에러 바운더리로 버블링하여 올라갑니다. 이는 error.js파일이 그것의 중첩된 모든 자식 세그먼트들의 에러를 핸들링할 것임을 의미합니다. 한 루트의 중첩된 폴더 안의 다양한 레벨에 error.js 파일을 위치함으로써, 더욱 조밀하거나 덜 복잡한 에러 UI를 만들어낼 수 있습니다.
  • error.js 바운더리는 동일한 세그먼트 안의 layout.js에서 발생한 에러는 핸들링하지 않습니다. 에러 바운더리는 레이아웃 컴포넌트 안에 포함되기 때문입니다.

Handling Errors in Layouts (레이아웃 안에서 에러 핸들링하기)

error.js 바운더리는 동일한 세그먼트 안의 layout.jstemplate.js 컴포넌트 안에서 발생한 에러는 캐치하지 않습니다. 이러한 의도적인 위계는 네비게이션과 같이, 형제 루트들 사이에 공유되는 중요한 UI를 볼 수 있는 상태로 유지시켜주며, 에러가 일어나더라도 잘 동작하도록 합니다.

특정한 레이아웃이나 템플릿 안에서 발생한 에러를 핸들링하려면, error.js 파일을 레이아웃의 부모 세그먼트에 위치시키세요.

루트 레이아웃이나 템플릿 안에서 발생한 에러를 핸들링하려면, global-error.js라는 error.js의 배리에이션 파일을 이용하세요.

Handling Errors in Root Layouts (루트 레이아웃 에러 핸들링하기)

루트 app/error.js 바운더리는 루트 app/layout.jsapp/template.js 컴포넌트 안에서 발생한 에러는 캐치하지 않습니다.

특별히 이러한 루트 컴포넌트들 안에서 에러를 핸들링하려면, 루트 app 디렉토리 안에 위치한 error.js의 배리에이션 파일인 app/global-error.js를 이용하세요.

루트 error.js와 달리, global-error.js에러 바운더리는 애플리케이션 전체를 감싸게 됩니다. 그리고 폴백 컴포넌트가 활성화된 경우에는 루트 레이아웃을 대치하게 됩니다. 이 때문에, global-error.js에는 반드시 그 안에 <html>태그와 <body>태그가 있어야만 합니다.

global-error.js는 애플리케이션 전체를 위한 "캐치-올" 에러 핸들링 UI가 될 수 있으며, 가장 덜 조밀한 에러 UI입니다. 루트 컴포넌트들은 통상적으로 덜 동적이기 때문에, 자주 발생하진 않을 것입니다. 그리고 다른 error.js 바운더리들이 대부분의 에러를 캐치하게 되겠죠.

global-error.js가 정의되었더라도, 여전히 폴백 컴포넌트가 전역적으로 공유되는 UI나 브랜딩을 포함하고 있는 루트 레이아웃 안에서 렌더링 될 루트 error.js를 정의하는 것을 추천합니다.

// app/global-error.tsx

export default function GlobalError({
	error,
    reset,
}: {
	error: Error;
    reset: () => void;
}) {
	return (
    	<html>
        	<body>
            	<h2>Something went wrong!</h2>
                <button onClick={() => reset()}>Try again</button>
            </body>
        </html>
    );
}

Handling Server Errors

데이터를 가져오는 도중이나 서버 컴포넌트 안에서 발생한 에러의 경우, Next.js는 Error 객체를 가장 가까운 error.js파일에 error prop으로 전달합니다.

next dev가 실행되는 동안, error은 서버 컴포넌트로부터 클라이언트의 error.js로 전달되고 시리얼라이즈됩니다. 프로덕션 레벨에서 next start가 실행되고 있을 때는, 보안을 위해 제네릭한 에러 메세지가 에러 메세지의 해시를 포함한.digesterror에 함께 전달될 겁니다. 이 해시는 상응하는 서버 로그로 사용될 수 있습니다.

profile
문학적 상상력과 기술적 가능성

0개의 댓글