본문 바로가기

Next.js

Next.js 11-7 Routing Error Handling

  error.js 파일 규칙을 사용하면 중첩된 경로에서 런타임 오류를 정상적으로 처리할 수 있다. React Error Boundary에서 경로 세그먼트와 중첩된 자식을 자동으로 래핑 한다. 세분성을 조정하기 위해 파일 시스템 계층 구조를 사용하여 특정 세그먼트에 맞는 오류 UI를 만든다. 나머지 앱 기능을 유지하면서 영향을 받는 세그먼트에 대한 오류를 격리한다. 전체 페이지를 다시 로드하지 않고 오류 복구를 시도하는 기능을 추가한다.

  경로 세그먼트 내에 error.js 파일을 추가하고 React 컴포넌트를 내보내서 오류 UI를 만든다.

// app/dashboard/error.tsx

'use client'; // Error components must be Client Components

import { useEffect } from 'react';

export default function Error({
  error,
  reset,
}: {
  error: Error;
  reset: () => void;
}) {
  useEffect(() => {
    // Log the error repoting service
    console.error(error);
  }, [error]);
  
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button
        onClick={
          // Attempt to recover by trying to re-render the segment
          () => reset()
        }
      >
        Try again
      </button>
    </div>
  )
}

 

  • error.js 작동 방식

  error.js는 중첩된 하위 세그먼트 또는 page.js 컴포넌트를 래핑 하는 React Error Boundary를 자동으로 생성한다. error.js 파일에서 내보낸 React 컴포넌트는 대체 컴포넌트로 사용된다. 오류 경계 내에서 오류가 발생하면 오류가 포함되고 대체 컴포넌트가 렌더링 된다. fallback error 컴포넌트가 활성화되면 error boundary 위의 레이아웃은 상태를 유지하고 대화식으로 유지되며 오류 컴포넌트는 오류에서 복구하는 기능을 표시할 수 있다.

 

  • 오류 복구

  때때로 오류의 원인은 일시적일 수 있다. 이러한 경우 다시 시도하면 문제가 해결될 수 있다. 오류 컴포넌트는 이 reset() 기능을 사용하여 사용자에게 오류 복구를 시도하라는 메시지를 표시할 수 있다. 실행되면 함수는 Error 경계의 내용을 다시 렌더링 하려고 시도한다. 성공하면 폴백 오류 컴포넌트가 다시 렌더링 된 결과로 대체된다.

// app/dashboard/error.tsx

'use client';

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

 

  • 중첩 경로

  특수 파일을 통해 생성된 React 컴포넌트는 특정 중첩 계층 구조로 렌더링 된다. 예를 들어 layout.js 및 error.js 파일을 모두 포함하는 두 개의 세그먼트가 있는 중첩된 경로는 다음과 같은 단순화된 컴포넌트 계층 구조로 렌더링 된다.

  중첩 컴포넌트 계층 구조는 중첩 경로에서 error.js 파일의 동작에 영향을 미친다. 오류는 가장 가까운 상위 오류 경계까지 버블링 된다. 이는 error.js 파일이 모든 중첩 하위 세그먼트에 대한 오률 처리함을 의미한다. 라우트의 중첩된 폴더에서 서로 다른 수준에 error.js 파일을 배치하여 다소 세분화된 오류 UI를 얻을 수 있다. error.js 경계는 레이아웃 컴포넌트 내부에 오류 경계 중첩되어 있기 때문에 동일한 세그먼트의 layout.js 컴포넌트에서 발생하는 오류를 처리하지 않는다.

 

  • Handling Error in Layouts

  error.js 경계는 동일한 세그먼트의 layout.js 또는 template.js 컴포넌트에서 발생한 오류를 포착하지 않는다. 이 의도적인 계층 구조는 오류가 발생할 때 형제 경로(예: 탐색) 간에 공유되는 중요한 UI를 표시하고 작동하도록 유지한다. 

  특정 레이아웃 또는 템플릿 내의 오류를 처리하려면 레이아웃 상위 세그먼트에 error.js 파일을 배치한다.

 

  • Handling Errors in Root Layouts

  루트 app/error.js 경계는 루트 app/layout.js 또는 app/templete.js 컴포넌트에서 발생한 오류를 포착하지 않는다. 이러한 루트 컴포넌트의 오류를 구체적으로 처리하려면 루트 앱 디렉토리에 있는 app/global-error.js라는 error.js의 변형을 사용하면 된다.

  루트 error.js와 달리 global-error.js 오류 경계는 전체 애플리케이션을 감싸고 있고, 폴백 컴포넌트는 활성 상태일 때 루트 레이아웃을 대체한다. 이 때문에 global-error.js는 자체 <html> 및 <body> 태그를 정의해야 한다는 점에 유의해야 한다.

  global-error.js는 가장 세분화되지 않은 오류 UI이며 전체 애플리케이션에 대한 "포괄적" 오류 처리로 간주될 수 있다. 루터 컴포넌트는 일반적으로 덜 동적이며 다른 error.js 경계는 대부분의 오류를 포착하므로 자주 트리거될 가능성이 없다.

  global-error.js가 정의되더라도 전역적으로 공유되는 UI 및 브랜딩을 포함하는 루트 레이아웃 내에서 대체 컴포넌트가 렌더링 될 루트 error.js를 정의하는 것이 여전히 권장된다.

// app/global-error.tsx

'use client';

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 prop으로 가장 가까운 error.js 파일을 전달한다.

  당므 개발을 실행할 때 오류가 직렬화되어 서버 컴포넌트에서 클라이언트 error.js로 전달된다. 프로덕션에서 다음 시작을 실행할 때 보안을 보장하기 위해 일반 오류 메시지가 오류 메시지의 해시가 포함된 .digest와 함께 오류로 전달된다. 이 해시는 서버 로그에 해당하는 데 사용할 수 있다.

 

참조: Next.js 공식문서