report — 例外を例外ハンドラ経由で報告する

helper
  • カテゴリ: helper
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: report(Throwable $exception)(グローバル関数)
  • 関連: report_if / report_unless / logger / Log / throw_if
  • 変更履歴: 特になし

要点(TL;DR)

  • 目的:捕捉した例外を Laravel の例外ハンドラに渡してログ・通知・APMへ報告する
  • 最小:report($e);
  • 罠:
    • レスポンスは返らない(画面制御は別途必要)
    • 二重記録report() + Log::error()の併用)に注意
    • ジョブ失敗は自動報告されるため、無闇な多重 report() は避ける

概要

report() は、app/Exceptions/Handler.php の設定にもとづいて例外を報告するための最短手段です。ログ出力、外部エラートラッカー(Sentry / Flare など)や通知への送信は、ハンドラ側の設定や各例外の report() / context() 実装に委ねられます。UIやHTTP応答の生成は行わないため、報告応答は分けて設計します。

構文 / シグネチャ

// 例外をフレームワークの例外ハンドラに報告
function report(Throwable $exception): void;

// 条件付き報告(便利ヘルパ)
function report_if(bool $condition, Throwable $exception): void;
function report_unless(bool $condition, Throwable $exception): void;
  • 引数(表) 引数 型 必須 既定値 説明 exception Throwable ✅ なし 報告したい例外インスタンス
  • 戻り値void(返り値なし)
  • 例外/副作用:通常は例外を投げません。ハンドラ設定に従ってログ書き込み・通知・APM送信が実行されます(外部I/O発生)。

使用例

最小例

<?php

use Throwable;

try {
    riskyOperation();
} catch (Throwable $e) {
    report($e);          // ここでログ/APMに飛ぶ
    return response()->json(['ok' => false], 200); // 画面制御は別途
}

実務例:外部API失敗を報告しつつフォールバック

<?php

namespace App\Services;

use App\Exceptions\PaymentFailed;
use Illuminate\Support\Facades\Cache;
use Throwable;

class PaymentService
{
    public function charge(array $payload): bool
    {
        try {
            // 決済API呼び出し...
            return true;
        } catch (Throwable $e) {
            // 1) 文脈付き独自例外で報告
            report(new PaymentFailed(
                orderId: $payload['order_id'] ?? 0,
                gateway: 'Stripe',
                previous: $e,
            ));

            // 2) フォールバック(たとえば予約状態に退避)
            Cache::put("order:{$payload['order_id']}:pending", $payload, now()->addMinutes(10));

            // 3) 画面や上位層には失敗可視化のみ
            return false;
        }
    }
}
<?php
// 例外側でログ文脈を提供
namespace App\Exceptions;

use Exception;

class PaymentFailed extends Exception
{
    public function __construct(
        public int $orderId,
        public string $gateway,
        ?\Throwable $previous = null
    ) {
        parent::__construct('Payment failed', 0, $previous);
    }

    /** ログ/APMに追加される文脈 */
    public function context(): array
    {
        return ['order_id' => $this->orderId, 'gateway' => $this->gateway];
    }
}

よくある落とし穴・注意

  • 画面は変わらないreport()は「報告のみ」。HTTP応答は自分で返すか、例外を再throwしてフレームワークに任せる。
  • 二重記録report()後にLog::error()を重ねると重複しやすい。どちらか一方に統一。
  • dontReport リストHandler::$dontReport に入っている例外は既定で報告されない。必要に応じて調整。
  • ジョブ/コマンド:キューワーカーは失敗時に自動報告。catchして握り潰すなら明示的にreport()+リトライ設計を。
  • 個人情報context()PIIを直入れしない。マスキング運用を徹底。
  • 条件付き:大量ループ内は report_if() / report_unless()サンプリングや条件報告を。

代替・関連APIとの比較

  • report() vs Log::error()report()例外ハンドラ経由dontReport尊重・外部連携一元化)。Log::error()純粋にログ出力したいとき。
  • report_if / report_unless:条件に応じて簡潔に書ける。
  • throw_if / abort:フロー制御が主目的。報告はハンドラ側に委譲したいときに有効。
  • フレームワーク依存 / 純PHP代替:フレームワークに依存。純PHPならerror_log()や独自ロガーで代替。
  • コンテナ/グローバル状態:バインドされた ExceptionHandler とログ設定に依存(テストで差し替え可能)。

テスト例(Pest)

<?php

use Illuminate\Support\Facades\Log;

it('reports via exception report() method', function () {
    Log::spy();

    // report() メソッドを持つ匿名例外
    $e = new class extends Exception {
        public function report(): void
        {
            \Illuminate\Support\Facades\Log::info('reported');
        }
    };

    report($e);

    Log::shouldHaveReceived('info')->once()->with('reported');
});

トラブルシュート(エラー別)

症状/エラー原因対処
Call to undefined function report()Laravel外やブートストラップ不足Laravelアプリ内で実行。外部ならerror_log()等で代替
何も送信されない(Sentry等に出ない)dontReport対象 / 連携未設定Handler::$dontReport見直し、連携パッケージとDSN設定を確認
ログが重複するreport()Log::error()の併用 / 再報告どちらかに統一。独自例外のreport()内重複も確認
キューで大量通知ループ内で多重report()report_if()で条件化 / サンプリング / バッチ化

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする