error.js 파일 컨벤션은 중첩된 루트들 안에서 우아하게 런타임 에러를 핸들링할 수 있게 도와줍니다.
루트 세그먼트 안에 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>
);
}
error.js Works (error.js는 어떻게 동작할까요)
error.js는 자동으로 리액트 에러 바운더리를 생성하고, page.js 컴포넌트 또는 중첩된 자식 세그먼트를 감쌉니다.error.js파일로부터 익스포트된 리액트 컴포넌트는 폴백 컴포넌트로 사용됩니다.에러의 원인은 종종 일시적일 수 있습니다. 이러한 경우에는 간단하게 다시 시도하는 것을 통해 문제를 해결할 수 있습니다.
에러 컴포넌트는 유저가 에러를 회복하기 위한 시도를 할 수 있도록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>
);
}
특별한 파일들 (special files)를 통해 생성된 리액트 컴포넌트들은 특정한 중첩 위계 안에서 렌더링 됩니다.
예를 들어, 둘 다 각각의 layout.js와 error.js를 포함하고 있는, 한 중첩 루트 안의 두 세그먼트 파일들은 아래의 간소화된 컴포넌트 위계에 따라 렌더됩니다:

중첩된 컴포넌트 위계는 중첩된 루트 전반에 걸쳐 error.js 파일의 행동 양식에 아래와 같은 함의들을 갖습니다:
error.js파일이 그것의 중첩된 모든 자식 세그먼트들의 에러를 핸들링할 것임을 의미합니다. 한 루트의 중첩된 폴더 안의 다양한 레벨에 error.js 파일을 위치함으로써, 더욱 조밀하거나 덜 복잡한 에러 UI를 만들어낼 수 있습니다.error.js 바운더리는 동일한 세그먼트 안의 layout.js에서 발생한 에러는 핸들링하지 않습니다. 에러 바운더리는 레이아웃 컴포넌트 안에 포함되기 때문입니다.error.js 바운더리는 동일한 세그먼트 안의 layout.js나 template.js 컴포넌트 안에서 발생한 에러는 캐치하지 않습니다. 이러한 의도적인 위계는 네비게이션과 같이, 형제 루트들 사이에 공유되는 중요한 UI를 볼 수 있는 상태로 유지시켜주며, 에러가 일어나더라도 잘 동작하도록 합니다.
특정한 레이아웃이나 템플릿 안에서 발생한 에러를 핸들링하려면, error.js 파일을 레이아웃의 부모 세그먼트에 위치시키세요.
루트 레이아웃이나 템플릿 안에서 발생한 에러를 핸들링하려면, global-error.js라는 error.js의 배리에이션 파일을 이용하세요.
루트 app/error.js 바운더리는 루트 app/layout.js나 app/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>
);
}
데이터를 가져오는 도중이나 서버 컴포넌트 안에서 발생한 에러의 경우, Next.js는 Error 객체를 가장 가까운 error.js파일에 error prop으로 전달합니다.
next dev가 실행되는 동안, error은 서버 컴포넌트로부터 클라이언트의 error.js로 전달되고 시리얼라이즈됩니다. 프로덕션 레벨에서 next start가 실행되고 있을 때는, 보안을 위해 제네릭한 에러 메세지가 에러 메세지의 해시를 포함한.digest가 error에 함께 전달될 겁니다. 이 해시는 상응하는 서버 로그로 사용될 수 있습니다.