浜松のWEBシステム開発・スマートフォンアプリ開発・RTK-GNSS関連の開発はお任せください
株式会社シーポイントラボ
TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:静岡県浜松市中区富塚町1933-1 佐鳴湖パークタウンサウス2F

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

  • この記事いいね! (0)