Laravel のエラー画面は Laravel 6 以降は ignition というプロジェクトで作成されたエラーページを生成する様にしてあります。
facade/ignition: A beautiful error page for Laravel apps
このエラーページではデバッグモードらしくリクエストを処理するPHPプロセス中に投げられたクエリを見ることができます。
// このコードを実行すると下画像の画面が出ます。 \App\Models\Eloquents\User::first(); throw new \RuntimeException('hoge');
非常に便利なのですが JSON 形式のエラーレスポンスではこの恩恵にあずかることができません。
JSON 形式のエラーレスポンスにもクエリログを付与したくなります。JSON 形式のエラー(例外)レスポンスにPHPプロセス中に投げられたクエリログをつける方法が次です。
/** /app/Providers/AppServiceProvider.php */ enableQueryLog class AppServiceProvider extends ServiceProvider { /** * どのアプリケーションサービスでも自動実行されるメソッドです。 * * @return void */ public function boot(): void { // debug モード以外では SQL をロギングしない // 運用ルール次第では config('app.production') !== 'production' も増やして本番環境ではSQLをロギングしない、としてもいいかもしれません if (config('app.debug') !== true) { return; } // このプロセスのデータベース接続はクエリをロギングする様になります。 \DB::enableQueryLog(); } }
<?php /** /app/Exceptions/Handler.php */ // 例外ハンドラー namespace App\Exceptions; use App\Services\Cart\Exceptions\CartValidationException; use App\Services\Cart\Exceptions\ItemInCartRuleValidationException; use Exception; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class Handler extends ExceptionHandler { public function render($request, Exception $exception): Response { $response = parent::render($request, $exception); if($response instanceof JsonResponse){ // データベース接続でロギングされたクエリを取得します。 $queryLog = \DB::getQueryLog(); // ベースとなる親で生成されたJSONレスポンスを取得 // JSON 文字列を元にレスポンス用の配列を構築 $content = $response->getContent(); $baseContent = json_decode($content, true); // レスポンス用配列にクエリログを追加 $newContent = array_merge(['queryLog' => $queryLog],$baseContent); // 構築した配列をレスポンスにセット $response->setData($newContent); return $response; // フロントに返す } return $response; } }
この様にするとJSONレスポンスを要求するリクエストの例外レスポンスにクエリ内容が追加されます。これを用いると API を叩いた時のエラーを解析しやすくなります。