[Next.js] 에러 핸들링

파이리·2023년 8월 2일
0

Next.js

목록 보기
9/18

error.js 파일 규칙을 사용하면 중첩 라우팅에서 런타임 오류를 우아하게 처리할 수 있습니다.

  • 경로 세그먼트와 그 중첩된 자식들을 React 에러 바운더리에서 자동으로 래핑합니다.

  • 파일 시스템 계층 구조를 사용하여 특정 세그먼트에 맞춘 오류 UI를 생성하여 세분화할 수 있습니다.

  • 앱의 나머지 기능은 유지하면서 영향을 받는 세그먼트에 대한 오류를 격리합니다.

  • 전체 페이지를 다시 로드하지 않고 오류에서 복구를 시도하는 기능을 추가합니다.

Route Segment 안에 error.js 파일을 추가하고 React 컴포넌트를 내보내서 오류 UI를 만듭니다.

'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 to an error reporting 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 컴포넌트가 폴백 컴포넌트로 사용됩니다.

  • Error Boundary 내에서 에러가 발생하면 에러가 포함되고 폴백 컴포넌트가 랜더링됩니다.

  • 폴백 오류 컴포넌트가 활성화되면 Error Boundary 위의 레이아웃은 해당 상태를 유지하고 대화형 상태를 유지하며 오류 컴포넌트는 오류를 복구하는 기능을 표시할 수 있습니다.

오류 복구

오류의 원인은 일시적은 것일 수 있습니다. 이러한 경우 다시 시도하기만 하면 문제가 해결될 수 있습니다.

오류 컴포넌트는 reset() 함수를 사용하여 사용자에게 오류에서 복구를 시도하라는 메세지를 표시할 수 있습니다. 이 함수가 실행되면 Error Boundary의 내용을 다시 랜더링하려고 시도합니다. 성공하면 폴백 오류 컴포넌트가 다시 랜더링한 결과로 대체됩니다.

'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>
  )
}

중첩 라우팅

특수 파일을 통해 생성된 React 컴포넌트 특정 중첩 계층 구조로 랜더링됩니다.

예를 들어 layout.js 파일과 error.js 파일이 모두 포함된 두 개의 세그먼트가 있는 중첩 라우팅은 다음과 같은 단순화된 컴포넌트 계층 구조로 랜더링됩니다.

중첩 컴포넌트 계층 구조는 중첩 라우팅에서 error.js 파일의 동작에 영향을 미칩니다.

  • 오류는 가장 가까운 상위 오류 경계까지 퍼집니다. 즉, error.js 파일은 중첩된 모든 하위 세그먼트에 대한 오류를 처리합니다. 경로의 중첩된 폴더에서 error.js 파일을 서로 다른 수준에 배치하면 어느 정도 세분화된 오류 UI를 구현할 수 있습니다.

  • Error Boundary가 해당 레이아웃 컴포넌트 내부에 중첩되어 있기 때문에 error.js Boundary는 동일한 세그먼트의 layout.js 컴포넌트에서 발생한 오류를 처리하지 않습니다.

레이아웃에서 오류 처리하기

error.js Boundary는 같은 세그먼트의 layout.js 또는 template.js 컴포넌트에서 발생한 오류를 포착하지 않습니다. 이 의도적인 계층 구조는 형제 경로 간에 공유되는 중요한 UI가 오류가 발생해도 계속 표시되고 작동하도록 유지합니다.

특정 레이아웃 또는 탬플릿 내에서 오류를 처리하려면 레이아웃 상위 세그먼트에 error.js를 배치하면 됩니다.

루트 레이아웃 또는 탬플릿 내에서 오류를 처리하려면, global-error.js라는 error.js의 변형을 사용합니다.

루트 레이아웃에서 오류 처리하기

루트 app/error.js Boundary는 루트 app/layout.js 또는 app/template.js 컴포넌트에서 발생하는 오류를 포착하지 않습니다.

이러한 루트 컴포넌트의 오류를 구체적으로 처리하려면 루트 앱 디렉터리에 있는 app/global-error.js라는 error.js의 변형을 사용하세요.

루트 error.js와 달리 global-error.js Error Boundary는 전체 애플리케이션을 감싸며 해당 폴백 컴포넌트가 활성화되면 루트 레이아웃을 대체합니다. 따라서 global-error.js에도 자체 <html><body> 태그를 정의해야 합니다.

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

global-error.js가 정의되어 있더라도 전역적으로 공유되는 UI 및 브랜딩을 포함하는 루트 레이아웃 내에서 랜더링될 폴백 컴포넌트가 있는 루트 error.js를 정의하는 것이 좋습니다.

'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>
  )
}

서버 오류 처리

데이터 불러오기 중 또는 서버 컴포넌트 내부에서 오류가 발생하면 Next.js는 오류 결과를 가진 객체를 가장 가까운 error.js 파일의 error 프로퍼티로 전달합니다.

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

profile
프론트엔드 개발자

1개의 댓글

comment-user-thumbnail
2023년 8월 2일

좋은 글 감사합니다.

답글 달기