概要
Laravel プロジェクトを作成すると、エラーと例外の処理はあらかじめ設定された状態で用意されています。 カスタマイズはbootstrap/app.php の withExceptions メソッドで行います。
例外処理フロー
例外が発生してからクライアントにレスポンスが返るまでの流れを示します。withExceptions クロージャに渡される $exceptions オブジェクトは Illuminate\Foundation\Configuration\Exceptions のインスタンスで、アプリケーション全体の例外ハンドリングを管理します。
デバッグ設定
config/app.php の debug オプションがエラー情報の表示量を制御します。
デフォルトでは .env の APP_DEBUG 環境変数の値が使われます。
例外のレポート
例外のレポートとは、例外をログに記録したり Sentry や Flare などの外部サービスに送信したりする処理です。 デフォルトではconfig/logging.php の設定に基づいてログに記録されます。
カスタムレポートコールバック
例外の種類によって異なるレポート処理をしたい場合はreport メソッドにクロージャを渡します。
Laravelはクロージャの型ヒントから例外の種類を判断します。
stop() を呼ぶか、false を返します。
report() ヘルパー
エラーページを表示せずに例外だけを報告したい場合は report() ヘルパーを使います。
重複レポートの防止
同じ例外インスタンスが複数回report() に渡されると、ログに重複エントリが作成されることがあります。
dontReportDuplicates() を設定すると、同じインスタンスは最初の1回だけ記録されます。
グローバルログコンテキスト
すべての例外ログに共通の情報を付与したい場合はcontext メソッドを使います。
利用可能であれば現在のユーザーIDは自動的に付与されます。
例外クラスへの context() メソッド追加
例外クラス自身に context() メソッドを定義すると、その例外に固有のコンテキスト情報をログに含められます。
ログレベルの変更
特定の例外を特定のログレベルで記録したい場合はlevel メソッドを使います。
例外レポートのスロットリング
大量の例外が発生する場合、throttle メソッドでレポート数を制御できます。
Limit を使います。
例外のレンダリング
レンダリングとは、例外を HTTP レスポンスに変換する処理です。 デフォルトでは Laravel が自動的に適切なレスポンスを生成しますが、カスタマイズも可能です。カスタムレンダリングコールバック
render メソッドにクロージャを渡して例外をレスポンスに変換します。
NotFoundHttpException など)のレンダリングも上書きできます。
クロージャが値を返さない場合は、デフォルトのレンダリングが使われます。
JSON / HTML の自動判定
Laravel はリクエストのAccept ヘッダーに基づいて HTML と JSON のどちらで返すかを自動判定します。
この判定ロジックをカスタマイズしたい場合は shouldRenderJsonWhen を使います。
レスポンス全体のカスタマイズ
respond メソッドを使うと、生成されたレスポンスをさらに加工できます。
カスタム例外クラス
app/Exceptions/ ディレクトリに独自の例外クラスを作成できます。
report() メソッドと render() メソッドを定義すると、bootstrap/app.php に設定を書かなくても自動的に呼ばれます。
例外クラスの作成
1
例外クラスを作成する
2
report() と render() を実装する
report() メソッドには型ヒントで依存性注入が使えます。Laravel のサービスコンテナが自動的に解決します。ShouldntReport インターフェース
レポート不要な例外には ShouldntReport インターフェースを実装します。
このインターフェースを実装した例外は一切レポートされません。
例外のスロー
abort() ヘルパー
アプリケーションのどこからでも HTTP エラーレスポンスを発生させられます。
abort_if() / abort_unless()
条件付きで例外をスローするヘルパーです。
例外のグローバルな制御
特定の例外を無視する
報告しない例外をdontReport で指定します。レンダリングのカスタムロジックは引き続き機能します。
dontReportWhen にクロージャを渡します。
Laravel はデフォルトで、404エラーや CSRF トークン不正 (419)、オリジン不一致 (403) などの一部の例外を自動的に無視しています。
Laravel が無視している例外を有効にする
デフォルトで無視されている例外をレポート対象に戻すにはstopIgnoring を使います。
HTTPエラーページ
Laravel では HTTP ステータスコードごとにカスタムエラービューを定義できます。カスタムエラービューの作成
resources/views/errors/ ディレクトリに、ステータスコードをファイル名としたBladeテンプレートを作成します。
$exception 変数を使ってエラー情報にアクセスできます。
デフォルトのエラーテンプレートを公開する
Laravel 標準のエラーページをカスタマイズの出発点として使いたい場合はvendor:publish で取得します。
フォールバックエラーページ
特定のステータスコードに対応するビューがない場合のフォールバックとして、4xx.blade.php と 5xx.blade.php を作成できます。
実践例: API 例外ハンドラー
API を提供するアプリケーションでは、例外を常に JSON で返す必要があります。 以下はbootstrap/app.php でAPIエラーを一元管理する実装例です。
カスタム API 例外クラスの実装
API 専用の基底例外クラスを作ると、各エンドポイントで統一したエラーレスポンスを返せます。まとめ
例外レポートのまとめ
例外レポートのまとめ
例外レンダリングのまとめ
例外レンダリングのまとめ
HTTP エラーページのまとめ
HTTP エラーページのまとめ
resources/views/errors/404.blade.phpなどのファイルを作るだけで自動的に使われる$exception変数でエラーの詳細にアクセスできるphp artisan vendor:publish --tag=laravel-errorsでデフォルトテンプレートを取得できる4xx.blade.php/5xx.blade.phpでフォールバックページを定義できる
本番環境でのベストプラクティス
本番環境でのベストプラクティス
APP_DEBUG=falseを必ず設定し、スタックトレースをユーザーに見せない- Sentry や Flare などの外部エラー追跡サービスと連携してエラーを一元管理する
throttle()を使って大量の例外が発生した際のログ溢れを防ぐ- API エンドポイントでは一貫したJSONエラーレスポンス形式を維持する