Logo

Next.js 14 App routerにおけるエラーハンドリングのやり方

エラーコンポーネントを用いたエラーハンドリングのやり方をご紹介します

前提

  • Next.js 14系
  • App router

結論

エラーコンポーネントであるerror.tsx(js/jsx)を適切なディレクトリに配置してエラー制御をエラーバウンダリに任せましょう。

エラーコンポーネントの仕組み

error.tsxを作成すると作成したディレクトリ配下のページコンポーネント内に自動的にエラーバウンダリの作成とラップをしてくれます。

そのため、ランタイム時のエラー(Client/Server Compnents共に)が発生した場合にError.tsx内のUIがフォールバックUIとして表示されるようになります。

(以前まではError Boundaryのクラスを別途作成する必要がありましたがerror.tsxコンポーネントの登場によって不要になりました)

Error.tsxのサンプル

下記は公式ドキュメントのサンプルですがClient ComponentsであればどんなUIでも問題ありません。(= use clinentが必須)


'use client' // Error components must be Client Components
 
import { useEffect } from 'react'
 
export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  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>
  )
}

エラーコンポーネントを入れてみる(実演)

このブログでも実演してみます。エラーコンポーネントの中身は上記のサンプルUIを使用します。

ディレクトリ構造としては、以下のような形です。(簡略化のため一部のみ表示)

/app
├── error.tsx
├── layout.tsx
├── page.tsx

page.tsx内では記事を表示するためにmicroCMSのAPIを叩いていますが、エラー再現のため内部でエラーをthrowさせます。

すると、以下の画像のようにpage.tsxで定義されたUIのみがエラーコンポーネントに置き換わり、画面がクラッシュすることなくUIが保持されています。

エラーコンポーネントの注意点

エラーコンポーネントは同階層のpageコンポーネントをラップしますがlayoutコンポーネントには適用されません。

→ つまり同階層のlayoutコンポーネントで発生したエラーはエラーコンポーネントを設定しても正常に処理されません。

対策としては、

  1. 親階層にエラーコンポーネントを配置して、エラーバウンダリの内側にlayoutコンポーネントを含めるようにする
  2. グローバル用のエラーコンポーネントであるglobal-error.tsx(js/jsx)を適用する

のどちらかを選択する必要があります。ネストした階層では1を選択し、RootLayoutなど1が選択できない場合は2を選択するのが良いでしょう。

また、2を選択した場合に、

  • global-error.js is only enabled in production. In development, our error overlay will show instead.

引用:https://nextjs.org/docs/14/app/building-your-application/routing/error-handling#handling-errors-in-root-layouts

と記載がある通り、Dev環境では表示されない仕様なのでそちらも合わせて注意しましょう。

参考記事