Laravel - 27. エラー処理 - Exceptionハンドラ
引き続きLaravelのエラー処理について学習していきましょう。ここではExceptionハンドラについて取り上げます。Exceptionハンドラとはスローされた例外を処理する仕組みです。たとえば前節では ModelNotFoundException
という例外がスローされていましたが、Exceptionハンドラを実装することでこのような例外インスタンスを適切に処理できるようになります。
Exceptionハンドラはデフォルトで app/Exceptions
フォルダ下に Handler.php
という名前で用意されています。テキストエディタで app/Exceptions/Handler.php
ファイルを開いてみましょう。
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
protected $dontReport = [
//
];
protected $dontFlash = [
'password',
'password_confirmation',
];
public function report(Exception $exception)
{
parent::report($exception);
}
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
}
上記のように $dontReport
、 $dontFlash
という2つのプロパティと report
、 render
と2つのメソッドが定義されています。2つのプロパティはレポート出力やフラッシュを抑制するためのもので、 report
メソッドには例外発生時のログ出力やレポートの送信などを実装し、 render
メソッドには例外発生時のレスポンスの出力を実装します。
ここでは次のように report
メソッドと render
メソッドを実装します。
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Log;
class Handler extends ExceptionHandler
{
# 省略...
public function report(Exception $exception)
{
if ($exception instanceof ModelNotFoundException) {
Log::warning("ModelNotFoundException");
}
parent::report($exception);
}
public function render($request, Exception $exception)
{
if ($exception instanceof ModelNotFoundException) {
return redirect("/hello");
}
return parent::render($request, $exception);
}
}
まずプログラムの先頭部分で use
キーワードを使って ModelNotFoundException
と Log
をインポートしています。
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Log;
report
メソッドの中では ModelNotFoundException
がスローされた場合に WARNING
ログを出力しています。また render
メソッドの中では ModelNotFoundException
がスローされた場合に "/hello"
にリダイレクトするように実装しています。
動作確認
それでは Handler.php
ファイルを追加したので、PHPのビルトインWebサーバを使ってWebアプリケーションを起動してみましょう。次のようにコマンドを入力します。
$ php artisan serve --host 0.0.0.0
Laravel development server started: http://0.0.0.0:8000
次にアドレスバーから以下のURLにアクセスしてみましょう。
http://localhost:8000/hello/show/100
実行結果のようにデータベースに存在しない id
を指定した場合は HelloController
の show
アクションから ModelNotFoundException
がスローされます。スローされた ModelNotFoundException
は Handler
クラスの report
メソッド、 render
メソッドで処理されるため最終的に "/hello"
にリダイレクトされます。
また report
メソッドによってログが出力されていることも確認しておきましょう。テキストエディタで storage/logs/laravel.log
ファイルを開いてみましょう。
[2020-09-08 02:31:12] local. WARNING: ModelNotFoundException
Handler
クラスの report
メソッドによって WARNING
ログが出力されているのがわかります。
まとめ
- Laravelの例外処理は
app/Exceptions/Handler.php
ファイルでカスタマイズできる Handler
クラス にはレポートの記録やログ出力用のreport
メソッド、画面表示用のrender
メソッドが用意されているreport
メソッドやrender
メソッドをオーバーライドすることで例外処理をカスタマイズできる