error.js

error ファイルを使用すると、予期しないランタイムエラーを処理し、フォールバック UI を表示できます。

error.js 特殊ファイル
'use client' // エラー境界はクライアントコンポーネントである必要があります

import { useEffect } from 'react'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // エラーをエラー報告サービスに記録
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button
        onClick={
          // セグメントを再レンダリングして復旧を試みる
          () => reset()
        }
      >
        Try again
      </button>
    </div>
  )
}

error.js はルートセグメントとそのネストされた子要素を React エラー境界でラップします。境界内でエラーが発生すると、error コンポーネントがフォールバック UI として表示されます。

error.js の動作

知っておくと便利:

  • React DevTools を使用すると、エラー境界を切り替えてエラー状態をテストできます。
  • エラーを親のエラー境界まで伝播させたい場合は、error コンポーネントのレンダリング時に throw できます。

リファレンス

Props

error

error.js クライアントコンポーネントに転送される Error オブジェクトのインスタンス。

知っておくと便利: 開発中は、クライアントに転送される Error オブジェクトはシリアライズされ、デバッグしやすいように元のエラーの message が含まれます。ただし、本番環境ではこの動作は異なり、エラーに含まれる可能性のある機密情報がクライアントに漏れるのを防ぎます。

error.message

  • クライアントコンポーネントから転送されたエラーには、元の Error メッセージが表示されます。
  • サーバーコンポーネントから転送されたエラーには、識別子付きの汎用メッセージが表示されます。これは機密情報の漏洩を防ぐためです。識別子 errors.digest を使用して、対応するサーバーサイドのログと照合できます。

error.digest

スローされたエラーの自動生成ハッシュ。サーバーサイドのログで対応するエラーと照合するために使用できます。

reset

エラーの原因は一時的な場合があります。このような場合、再度試すことで問題が解決することがあります。

エラーコンポーネントは reset() 関数を使用して、ユーザーにエラーからの復旧を試みるよう促すことができます。実行されると、この関数はエラー境界のコンテンツを再レンダリングしようとします。成功すると、フォールバックエラーコンポーネントが再レンダリングの結果に置き換えられます。

'use client' // エラー境界はクライアントコンポーネントである必要があります

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  )
}

グローバルエラー

あまり一般的ではありませんが、国際化を利用している場合でも、ルートレイアウトまたはテンプレートで global-error.js を使用してエラーを処理できます。グローバルエラー UI は独自の <html> タグと <body> タグを定義する必要があります。このファイルは、アクティブ時にルートレイアウトまたはテンプレートを置き換えます。

'use client' // エラー境界はクライアントコンポーネントである必要があります

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    // global-error には html タグと body タグを含める必要があります
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={() => reset()}>Try again</button>
      </body>
    </html>
  )
}

カスタムエラー境界による優雅なエラー復旧

クライアントでのレンダリングが失敗した場合、ユーザーエクスペリエンスを向上させるために、最後にサーバーでレンダリングされた UI を表示すると便利です。

GracefullyDegradingErrorBoundary は、エラーが発生する前に現在の HTML をキャプチャして保持するカスタムエラー境界の例です。レンダリングエラーが発生すると、キャプチャした HTML を再レンダリングし、ユーザーに通知する永続的な通知バーを表示します。

'use client'

import React, { Component, ErrorInfo, ReactNode } from 'react'

interface ErrorBoundaryProps {
  children: ReactNode
  onError?: (error: Error, errorInfo: ErrorInfo) => void
}

interface ErrorBoundaryState {
  hasError: boolean
}

export class GracefullyDegradingErrorBoundary extends Component<
  ErrorBoundaryProps,
  ErrorBoundaryState
> {
  private contentRef: React.RefObject<HTMLDivElement>

  constructor(props: ErrorBoundaryProps) {
    super(props)
    this.state = { hasError: false }
    this.contentRef = React.createRef()
  }

  static getDerivedStateFromError(_: Error): ErrorBoundaryState {
    return { hasError: true }
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    if (this.props.onError) {
      this.props.onError(error, errorInfo)
    }
  }

  render() {
    if (this.state.hasError) {
      // ハイドレーションなしで現在の HTML コンテンツをレンダリング
      return (
        <>
          <div
            ref={this.contentRef}
            suppressHydrationWarning
            dangerouslySetInnerHTML={{
              __html: this.contentRef.current?.innerHTML || '',
            }}
          />
          <div className="fixed bottom-0 left-0 right-0 bg-red-600 text-white py-4 px-6 text-center">
            <p className="font-semibold">
              An error occurred during page rendering
            </p>
          </div>
        </>
      )
    }

    return <div ref={this.contentRef}>{this.props.children}</div>
  }
}

export default GracefullyDegradingErrorBoundary

バージョン履歴

バージョン変更点
v15.2.0開発環境でも global-error が表示されるようになりました。
v13.1.0global-error が導入されました。
v13.0.0error が導入されました。

On this page