【Laravel】例外が発生した時、そのプロセス中で走ったSQLをJSONレスポンスに含める

 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 を叩いた時のエラーを解析しやすくなります。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG