エラーハンドリング

このドキュメントでは、Next.jsアプリケーションにおける開発時、サーバーサイド、クライアントサイドのエラーハンドリング方法について説明します。

開発時のエラーハンドリング

Next.jsアプリケーションの開発フェーズでランタイムエラーが発生すると、オーバーレイが表示されます。これはウェブページを覆うモーダルで、next devを使用した開発サーバー(pnpm devnpm run devyarn devbun devなど)で実行中にのみ表示され、本番環境では表示されません。エラーを修正するとオーバーレイは自動的に消えます。

以下はオーバーレイの例です:

開発モード時のオーバーレイ例

サーバーエラーの処理

Next.jsはデフォルトで静的500ページを提供し、アプリケーション内で発生するサーバーサイドエラーを処理します。また、pages/500.jsファイルを作成することでこのページをカスタマイズできます。

500ページを用意しても、アプリケーションユーザーに具体的なエラー内容は表示されません。

特定のランタイムエラー(例:file not found)を処理するには404ページも使用できます。

クライアントエラーの処理

Reactのエラー境界(Error Boundaries)を使用すると、クライアント側でJavaScriptエラーを優雅に処理でき、アプリケーションの他の部分は引き続き動作します。ページのクラッシュを防ぐだけでなく、カスタムフォールバックコンポーネントを表示したり、エラー情報を記録したりできます。

Next.jsアプリケーションでエラー境界を使用するには、クラスコンポーネントErrorBoundaryを作成し、pages/_app.jsファイル内のComponentプロップをラップする必要があります。このコンポーネントは以下を担当します:

  • エラー発生時にフォールバックUIをレンダリング
  • アプリケーション状態をリセットする手段を提供
  • エラー情報の記録

React.Componentを拡張してErrorBoundaryクラスコンポーネントを作成できます。例:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props)

    // エラーの有無を追跡する状態変数を定義
    this.state = { hasError: false }
  }
  static getDerivedStateFromError(error) {
    // 次のレンダリングでフォールバックUIが表示されるよう状態を更新
    return { hasError: true }
  }
  componentDidCatch(error, errorInfo) {
    // 独自のエラーロギングサービスを使用可能
    console.log({ error, errorInfo })
  }
  render() {
    // エラーが発生したか確認
    if (this.state.hasError) {
      // 任意のカスタムフォールバックUIをレンダリング可能
      return (
        <div>
          <h2>エラーが発生しました!</h2>
          <button
            type="button"
            onClick={() => this.setState({ hasError: false })}
          >
            再試行
          </button>
        </div>
      )
    }

    // エラーがない場合は子コンポーネントを返す
    return this.props.children
  }
}

export default ErrorBoundary

ErrorBoundaryコンポーネントはhasError状態を追跡します。この状態変数の値は真偽値で、trueの場合ErrorBoundaryコンポーネントはフォールバックUIをレンダリングします。それ以外の場合は子コンポーネントをレンダリングします。

ErrorBoundaryコンポーネントを作成したら、pages/_app.jsファイルでインポートし、Next.jsアプリケーションのComponentプロップをラップします。

// ErrorBoundaryコンポーネントをインポート
import ErrorBoundary from '../components/ErrorBoundary'

function MyApp({ Component, pageProps }) {
  return (
    // ComponentプロップをErrorBoundaryコンポーネントでラップ
    <ErrorBoundary>
      <Component {...pageProps} />
    </ErrorBoundary>
  )
}

export default MyApp

Reactのドキュメントでエラー境界についてさらに学べます。

エラーの報告

クライアントエラーを監視するには、Sentry、Bugsnag、Datadogなどのサービスを使用します。