Exception reporting

Exception reporting is the core of the SDK. Once configured, every exception Laravel reports is forwarded to your dashboard.

Automatic capture

During boot the SDK registers an additive reportable() callback on the application's exception handler:

php
$handler->reportable(function (Throwable $e): void {
    app(Monitor::class)->report($e);
});

Because the callback is additive, it does not replace or suppress your existing logging or any other reportable handlers, it simply forwards a copy to Quiet Guard. Any exception that reaches the handler (uncaught exceptions, or anything you pass to report()) is captured, except one raised while serving a request that matches ignore_paths: see Configuration.

Capture is fail-safe: a network outage, a misconfiguration or a server error inside the SDK is swallowed and never propagates to the host application.

Manual reporting

Use the Monitor facade to report a handled exception explicitly:

php
use QuietGuard\LaravelMonitor\Facades\Monitor;

try {
    $this->chargeCustomer($order);
} catch (\Throwable $e) {
    Monitor::report($e);

    // Re-throw or recover as you see fit.
    throw $e;
}

Monitor::report() never throws. It silently does nothing when reporting is disabled, when the server URL/key is missing, or when the current environment is not in the allowlist.

You can resolve the same object from the container:

php
app(\QuietGuard\LaravelMonitor\Monitor::class)->report($e);

What gets sent

Each report is posted to the server's /api/v1/ingest endpoint and contains:

The exception

  • class, message, code, file and line;
  • the complete stack trace by default (MONITOR_TRACE_LIMIT=0): every frame, so deep errors keep their origin; set a frame count to trim payloads. Each frame is reduced to file, line, function, class and type (arguments are never sent, they may contain secrets).

Context

  • environment, release (from MONITOR_RELEASE), php_version, laravel_version, occurred_at (ISO 8601);
  • source: console for CLI/queue, or http for web requests.

For HTTP requests the context additionally includes:

  • url and method;
  • request: headers, query string and body: with the body's password / password_confirmation removed and the whole structure passed through the scrubber;
  • user: the authenticated user's identifier only (id), never their attributes.

Scrubbing

Before any payload leaves the application, request and context data are recursively scrubbed: any key whose name contains one of the configured terms (case-insensitive) has its value replaced with [scrubbed].

The default terms are:

password, password_confirmation, passphrase, token, secret,
authorization, cookie, php_auth_pw, api_key, access_token,
referer, referrer, x-forwarded-for, x-real-ip, cf-connecting-ip,
true-client-ip, x-client-ip, forwarded

To add your own, publish the config (php artisan vendor:publish --tag=monitor-config) and extend the scrub array in config/monitor.php:

php
'scrub' => [
    ...config('monitor.scrub'),
    // your own:
    'credit_card',
    'iban',
],

Keep every shipped term unless you mean to drop it. Rewriting the array by hand is how passphrase and the visitor IP headers quietly leave the list.

Matching is by substring, so api_key also masks stripe_api_key, and token masks csrf_token.

Masking by the shape of the value

The scrub list above looks at the field name. It does not see an address written in the middle of an error message, in a URL segment, or in a field somebody called reference.

The redact list looks at the value itself, on your own server, before anything is sent:

php
'redact' => ['email', 'iban', 'nir', 'card', 'phone'],

Shapes that carry a check digit are verified rather than merely matched: a sixteen digit order reference is not taken for a card number, and an IBAN has to pass mod 97. Each masked value names what was hidden, for example User [redacted:email] not found, so the message stays readable.

Remove the patterns that produce false positives on your data, or set 'redact' => [] to switch it off. For your own shapes:

php
'redact_custom' => ['customer_ref' => '/CUST-\d{6}/'],

Sending in the background

When MONITOR_QUEUE is set, exceptions are dispatched as a SendExceptionToMonitor queued job (2 attempts) instead of being sent inline. This keeps reporting off the request's critical path. See Configuration.

Server-side grouping

The SDK only sends data; the server groups occurrences into issues by fingerprint, reopens regressions, and correlates releases with commits. See the server documentation for how issues are displayed and managed.

You are reading the Laravel SDK v1.0 documentation.