Laravel 学習記録 #016 例外処理を試して学ぶ
Laravelの例外処理について学習したものをまとめてます。
例外処理はエラーハンドリングは標準機能として
App\Exceptions\Handlerクラスがやってくれています。
このあたりをいじれば色々できそうです。
今回は以下の2点について試してみました。
・例外発生時にログテーブルへ記録する
・例外発生時に独自で作成したビューを表示させる
例外発生時にログテーブルへ記録する
準備として、テーブル、モデルを作成します。
エラーログテーブルを作成
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('error_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->nullable();
$table->string('user_name')->nullable();
$table->string('controller');
$table->string('action');
$table->boolean('error_flag');
$table->text('message');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('error_logs');
}
};
合わせてモデルを作成
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ErrorLog extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'user_name',
'controller',
'action',
'error_flag',
'message',
];
}
では、本題のログテーブルへの登録をします。
登録内容はユーザー情報やコントローラー名、アクション名、メッセージなどです。
Handlerクラスのregisterメソッドに追加します。
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
use App\Models\ErrorLog; // 追加
use Illuminate\Support\Facades\Auth; // 追加
class Handler extends ExceptionHandler
{
/**
* Register the exception handling callbacks for the application.
*/
public function register(): void
{
$this->reportable(function (Throwable $e) {
// 登録内容
$userId = null;
$userName = null;
// ログイン済みの場合ユーザー情報追加
if(Auth::check()) {
$user = Auth::user();
$userId = $user->id;
$userName = $user->name;
}
$controller = class_basename(request()->route()->getController());
$action = request()->route()->getActionMethod();
$errorFlag = true;
$message = $e->getMessage();
// ログをデータベースに保存
ErrorLog::create([
'user_id' => $userId,
'user_name' => $userName,
'controller' => $controller,
'action' => $action,
'error_flag' => $errorFlag,
'message' => $message,
]);
});
}
}
これで、例外発生時にDBへ登録する処理が準備できました。
コントローラーでExceptionをスローしてみます。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth; // 追加
class ExceptionController extends Controller
{
public function index()
{
// 仮ログイン
Auth::login(User::find(1));
// 例外スロー
throw new \Exception('例外エラーをDB登録');
return view('exception');
}
}
これでアクセスすると例外エラーが発生します。
これで無事に登録できているか、ErrorLogモデルを取得してます。
"id" => 1
"user_id" => 1
"user_name" => "ユーザー1"
"controller" => "ExceptionController"
"action" => "index"
"error_flag" => 1
"message" => "例外エラーをDB登録"
"created_at" => "2023-12-30 05:08:33"
"updated_at" => "2023-12-30 05:08:33"
問題なく登録されているようです。
これで例外発生時にログテーブルへの登録はできました。
例外発生時に独自で作成したビューを表示させる
これもよくある処理ですね。
LaravelではHTTPステータスコードのカスタムエラーページを簡単に作成できます。
resources/views/errors/[ステータスコード].blade.php
という命名のファイルを用意するだけです。
サーバーエラー用に500.blade.phpを作成します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>エラー</title>
</head>
<body>
<h1>Error:500</h1>
<p>システムエラーが発生しました。</p>
<p>時間を空けてから再度お試しいただくか、システム管理者にお問い合わせください。</p>
</body>
</html>
デバッグモードがオンになっているとLaravelのエラーページが表示されるのでオフにして確認が必要です。
// .envファイル
APP_DEBUG=false
これで先程と同様の確認をすると、上記作成ページが表示されます。
いや、全部のステータスコード作成めんどいな
例外発生時は全部同じ画面でいいんだよなって場合は
Handlerクラスにrenderメソッドに定義でいいんですかね。
以下のファイルを作成して、例外発生時に表示します。
resources/views/errors/fallback.blade.php
public function render($request, Throwable $exception)
{
return response()->view('errors.fallback');
}
これで例外発生時にエラーページを表示できました。
まだまだ、実務で使う際には気をつけるべき点が結構ありそうですね。
例外処理はプロジェクトごとに方針異なることが多々あるので、そこに合わせてやっていきましょう。
この記事が気に入ったらサポートをしてみませんか?