[Next.js] Error UI, Error Handling

프로젝트를 빌드한 후에 에러가 발생하면 사용자는 next.js의 기본 에러메세지가 표시된 페이지를 확인하게 된다

 

이런 UI말고 우리가 의도한 UI로 사용자에게 재시도를 유도할 수 있게하려면 어떻게 할 수 있을까?

Error UI를 만들기위한 기능도 넥스트에서 기본으로 제공하고 있다.

 

 

Error UI 만들기

1) route segment 폴더에 error.tsx 파일을 생성한다.

2) error.tsx는 반드시 클라이언트 컴포넌트여야한다! ('use client')

- 리액트의 error boundary와 연관

- 에러 바운더리는 클래스 컴포넌트로 작성되어있고, 리액트 컴포넌트 트리 내에서 발생하는 오류를 잡아내 fallback UI를 렌더링하는 역할을 한다

- 따라서 클라이언트 측에서 오류를 처리하기 위해서는 오류 컴포넌트가 클라이언트 컴포넌트로 정의되어야 함!

3) 에러가 발생했을 때 노출하고싶은 에러 페이지를 만들어준다.

 

 

Global Error

하지만 error.tsx는 하위 요소의 에러만 잡을 수 있기 때문에 가장 최상위 페이지의 에러는 잡지 못한다.

그 때 global-error.tsx를 활용할 수 있다!

 

1) app폴더(최상단)에 global-error.tsx 생성

2) next.js 도큐먼트의 글로벌에러 코드를 추가

use client';

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

 

3) dev 모드에서는 동작하지 않고 production 모드에서만 동작하기 때문에 UI를 바로 확인할 수는 없다

 

 

refresh와 startTransition

페이지에서 일시적인 에러가 발생했을 때 다시 그 페이지를 시도하게 하기위해 사용할 수 있다.

const Page = () => {
  if (Math.random() > 0.5) {
    throw new Error("일시적 오류 발생");
  }

  return (
    <div>
      <h1 className="font-bold">에러 테스트용 페이지</h1>
      <p>이 페이지에선 50% 확률로 일시적인 에러가 발생합니다.</p>
    </div>
  );
};

export default Page;
'use client';

import { useRouter } from 'next/navigation';
import { startTransition } from 'react';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  const { refresh } = useRouter();

  return (
    <div>
      <h2>Something went wrong!</h2>
      <h2>{error.message}</h2>
      <button
        onClick={() =>
          startTransition(() => {
            refresh();
            reset();
          })
        }
      >
        Try again
      </button>
    </div>
  );
}