Next.js 14 시작하기 #14 Error Handling

HanHyuk·2024년 1월 8일

Next.js

목록 보기
15/18

error.js

  • 기존의 에러 발생 시 위와 같이 페이지가 출력되는데 이는 좋은 UX가 아니다.
  • error.js를 만들어주면 해당 라우트 세그먼트에서 에러 발생 시 위의 에러 페이지 대신 커스텀한 에러 페이지를 출력할 수 있다.
// app/product/[productId]/reviews/[reviewId]/page.js

import { notFound } from "next/navigation";

function getRandomInt(count) {
  return Math.floor(Math.random() * count)
}

export default function ReviewDetail({ params }) {
  const random = getRandomInt(2)

  if (random === 1) {
    throw new Error("Error loading review");
  }

  if (parseInt(params.reviewId) > 1000) {
    notFound();
  }

  return (
    <h1> {params.reviewId}th Review for product {params.productId}</h1>
  )
}

// app/product/[productId]/reviews/[reviewId]/error.js

'use client'

export default function ErrorBoundary({error}) {
  return <div>{error.message}</div>
}

해당 라우트 세그먼트에 랜덤으로 에러가 발생하는 상황을 발생시킨 뒤 error.js에 에러 메시지가 출력되는 커스텀 에러 페이지를 만들게 되면


에러 발생 안할 경우


에러 발생한 경우

와 같이 error.js가 출력되게 된다.

Recovering from Errors

  • 에러 발생 시 넘어가진 error.js 페이지에서 recover 하는 방법
// .../error.js
'use client'

export default function ErrorBoundary({error, reset}) {
  return <div>
    {error.message}
    <button onClick={reset}> Try again</button>
  </div>
}

// .../page.js
'use client'
import { notFound } from "next/navigation";


function getRandomInt(count) {
  return Math.floor(Math.random() * count)
}

export default function ReviewDetail({ params }) {
  const random = getRandomInt(2)

  if (random === 1) {
    throw new Error("Error loading review");
  }

  if (parseInt(params.reviewId) > 1000) {
    notFound();
  }

  return (
    <h1> {params.reviewId}th Review for product {params.productId}</h1>
  )
}

이와 같이 error.js의 ErrorBoundary의 reset기능을 활용해 간단하게 기존의 페이지를 리렌더링 할 수 있음(설정해둔 확률로 에러 발생)

중첩 라우트에서의 Error handling

  • 에러는 가장 가까운 상위 Error Boundary까지 전파됨
  • error.js(error.tsx)는 같은 라우트 세그먼트 내에 있는 모든 중첩된 자식 세그먼트에서의 에러까지 처리해준다
  • 라우트의 중첩된 폴더 내에서, error.js(error.tsx)파일을 다른 레벨에 배치함으로써 보다 세밀한 수준의 에러 핸들링 달성이 가능함
  • 즉 가장 가까운 상위 디렉토리의 error.js를 따라가기 때문에 큰 범위에서의 에러관리, 세밀한 범위에서의 에러관리가 모두 가능하다.
  • 예를 들어, /product/error.js가 있다고 하위 디렉토리에 error.js가 없다면 /product 하위의 모든 라우트 세그먼트에서 에러가 발생 시 /product/error.js의 에러 페이지를 띄우게 됨

레이아웃에서의 Error handling

  • 에러 바운더리는 동일한 디렉토리(폴더)에 있는 레이아웃에 생긴 에러를 잡아 낼 수 없는데, 그 이유는 에러 바운더리보다 레이아웃이 더 상위 범주(계층)에 속하고 있기 때문임
  • 따라서 해당 레이아웃에 생기는 에러를 catch하기 위해서는 더 상위에 있는 폴더에 error.js를 위치시키면 된다.
  • 예를 들어 /product/[productId]/layout.js에서의 에러를 커스텀 하기 위해서는 /product/error.js와 같은 디렉토리에 위치시켜야 한다는 뜻이다.
profile
선한 영향력을 펼치는 개발자가 되겠습니다.

0개의 댓글