LaravelのHandler.phpで例外をカスタマイズする方法!初心者向け完全ガイド
生徒
「Laravelでエラーが起きたとき、自分で好きなエラー画面を表示させることってできますか?」
先生
「できますよ。Laravelにはapp/Exceptions/Handler.phpというファイルがあって、そこを編集するとエラーの処理を自由にカスタマイズできます。」
生徒
「難しそうに聞こえますが、初心者でも理解できますか?」
先生
「基本を押さえれば大丈夫です。実際のコードを見ながら一つずつ説明しますね。」
1. 例外(Exception)とは何か?基本から理解しよう
プログラムを動かしていると、想定外の状況が起きることがあります。たとえば、存在しないページにアクセスされたとき、データベースに接続できなかったとき、などです。このような「想定外の出来事」のことをプログラムの世界では例外(Exception)と呼びます。
例外という言葉が難しく感じるかもしれませんが、身近なもので例えると「レストランで注文した料理が売り切れだったとき」のようなイメージです。普通の流れとは違う状況が発生して、何らかの対処が必要になる場面のことです。
Laravelでは、この例外が発生したときにどう対処するかをまとめて管理するファイルがapp/Exceptions/Handler.phpです。このファイルを上手に使いこなすことで、エラーが起きたときにユーザーへ丁寧なメッセージを見せたり、エラー内容をログに記録したりと、さまざまな処理を自動的に行うことができます。
2. Handler.phpの基本的な構造を知ろう
app/Exceptions/Handler.phpは、Laravelプロジェクトを作成すると最初から用意されているファイルです。このファイルの中には、例外が発生したときに動く処理が書かれています。
Laravelのバージョンによって書き方が少し変わりますが、Laravel9以降ではregister()というメソッド(処理のまとまり)の中に例外の処理を登録していくスタイルになっています。メソッドとは、クラス(設計図)の中に書かれた「やること」をまとめたものです。
まず、Handler.phpの基本的な形を見てみましょう。
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
// 例外処理の登録をするメソッド
public function register(): void
{
// ここに例外の処理を書いていく
}
}
register()メソッドの中に、どんな例外が起きたときにどう動くかを書き込んでいきます。最初はシンプルな構造なので、少しずつ中身を追加していくイメージで覚えていきましょう。
3. 特定の例外をキャッチして処理する方法
Laravelではrenderable()というメソッドを使うと、特定の種類の例外が発生したときに「どんな画面を表示するか」を自分で決めることができます。キャッチとは、例外を受け取って対処することを意味する言葉です。
たとえば「ページが見つからなかった」ときに発生するModelNotFoundException(モデル見つからない例外)が起きたとき、自分で用意したエラーページを表示させたい場合は以下のように書きます。
ModelNotFoundExceptionとは、データベースからデータを探したが見つからなかったときにLaravelが自動で発生させる例外の一種です。
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Throwable;
class Handler extends ExceptionHandler
{
public function register(): void
{
// ModelNotFoundExceptionが発生したときの処理
$this->renderable(function (ModelNotFoundException $e) {
return response()->view('errors.not-found', [], 404);
});
}
}
このコードでは、ModelNotFoundExceptionが起きたときにresources/views/errors/not-found.blade.phpというビュー(画面)を表示して、HTTPステータスコード404(ページが見つからないことを示す番号)を返します。HTTPステータスコードとは、ウェブサーバーがブラウザに返す「状態を表す数字」のことです。
4. reportable()でエラーをログに記録する方法
例外が起きたとき、画面に表示するだけでなく「記録として残しておきたい」場合があります。そんなときに使うのがreportable()メソッドです。このメソッドを使うと、特定の例外が発生したときにログファイルへの書き込みや、外部サービスへの通知などを行うことができます。
ログとは、プログラムが動いた記録を残したファイルのことです。何か問題が起きたときにあとから原因を調べるのに役立ちます。
<?php
use Illuminate\Support\Facades\Log;
use App\Exceptions\PaymentException;
public function register(): void
{
// PaymentExceptionが発生したときにログへ記録する
$this->reportable(function (PaymentException $e) {
Log::error('決済処理でエラーが発生しました: ' . $e->getMessage());
});
}
このコードでは、PaymentException(独自に作った決済エラー用の例外クラス)が発生したとき、Log::error()を使ってエラーの内容をログに書き込んでいます。$e->getMessage()は、例外に含まれているエラーメッセージの文章を取り出すメソッドです。
実際の開発では、決済の失敗や重要なデータの更新ミスなど、見逃してはいけないエラーをこのようにして記録しておくことがとても大切です。
5. 独自の例外クラスを作成する方法
Laravelでは自分でオリジナルの例外クラスを作ることができます。たとえば「会員登録が必要なページに未登録のユーザーがアクセスした」など、アプリ独自のエラーに名前をつけて管理できるようになります。
独自の例外クラスは、ターミナルで以下のコマンドを実行すると自動生成されます。
// ターミナルで実行するArtisanコマンド
php artisan make:exception MemberOnlyException
このコマンドを実行するとapp/Exceptions/MemberOnlyException.phpというファイルが作られます。Artisanコマンドとは、Laravelに最初から用意されているコマンドラインツールで、ファイルの自動生成など様々な作業を簡単に行える機能です。
生成されたファイルにメッセージや処理を追加することで、独自のエラーとして管理できるようになります。独自例外を使うことで、コードが整理されて読みやすくなるという利点もあります。
6. HTTPエラーページをカスタマイズする方法
Laravelでは、404(ページが見つからない)や500(サーバー内部エラー)などのHTTPエラーが発生したときに表示するページを、自分でデザインしたものに変えることができます。
やり方はシンプルで、resources/views/errorsフォルダの中に、エラーコードと同じ名前のbladeファイルを作るだけです。たとえば404エラー用のページを作りたい場合は以下のようなファイルを用意します。
<!-- resources/views/errors/404.blade.php -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ページが見つかりません</title>
</head>
<body>
<h1>404 - ページが見つかりません</h1>
<p>お探しのページは存在しないか、移動した可能性があります。</p>
<a href="/">トップページへ戻る</a>
</body>
</html>
このファイルを置くだけで、404エラーが起きたときに自動的にこの画面が表示されます。デフォルト(初期設定)のエラー画面はそっけない見た目ですが、このようにカスタマイズすることでユーザーに親切なメッセージを伝えることができます。サービスの雰囲気に合ったデザインにすることで、エラーが起きてもユーザーが困惑しにくくなります。
7. $dontReport で特定の例外をログから除外する方法
Laravelでは例外が発生するとデフォルトでログに記録されますが、記録する必要がない例外もあります。たとえば「ユーザーが自分でページを間違えてアクセスした」ような404エラーは、毎回ログに残す必要はないケースも多いです。
そういった場合は、Handler.phpの中にある$dontReportプロパティ(クラスが持つ変数のようなもの)に例外クラスを追加することで、その例外をログから除外できます。
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Database\Eloquent\ModelNotFoundException;
class Handler extends ExceptionHandler
{
// ログに記録しない例外クラスを指定する
protected $dontReport = [
ModelNotFoundException::class,
];
public function register(): void
{
//
}
}
このように設定しておくと、ModelNotFoundExceptionが発生してもログには何も書き込まれません。ログファイルが不要な情報で埋まってしまうのを防げるため、本当に重要なエラーだけを記録するためのログ管理がしやすくなります。開発が進んでエラーの種類が増えてきたら、この設定を活用してみましょう。