Excepțiile din Laravel, ca notificări pe telefon

Actualizat pe 5 octombrie 2026 3 min de lectură

Laravel raportează deja excepțiile: în log și, cu un canal de log ca Slack, într-un chat. Problema apare când aceeași excepție se repetă de 300 de ori într-un minut. Vrei să afli o singură dată, cu destule detalii ca să poți face ceva, apoi să fii lăsat în pace până se strică altceva.

Ghidul pune asta la punct cu pachetul honk-me/honk-me și Laravel 13. Excepțiile devin notificări, repetările aceluiași eșec intră într-un singur grup, iar sarcinile programate te anunță când eșuează și când merg din nou.

Înainte să începi

  • Laravel 13 pe PHP 8.3 sau mai nou.
  • Un cont Honk (deocamdată, doar pe bază de invitație: cere acces) și un proiect cu o cheie API: în aplicația web, deschide proiectul, apoi Chei.

1. Instalează pachetul

composer require honk-me/honk-me
# publishes config/honk.php and adds HONK_URL and HONK_KEY to .env.example
php artisan honk:install

Pune URL-ul serverului și cheia în .env. Cheia nu intră niciodată într-un commit; în .env.example lași doar valori goale.

HONK_URL=https://honk-me.app
HONK_KEY=honk_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Verifică conexiunea. honk:test trimite un Claxon ușor și afișează ID-ul mesajului:

php artisan honk:test         # sends a light honk and prints the message id
php artisan about --only=honk # URL, key prefix (never the secret), queue, Context metadata

2. Raportează excepțiile

O singură linie în bootstrap/app.php:

// bootstrap/app.php
use HonkMe\Laravel\Facades\Honk;

->withExceptions(function (Exceptions $exceptions): void {
    $exceptions->report(Honk::reportable());
})

De acum, fiecare excepție raportată devine un Claxon lung, trimis ca problemă. Trei detalii țin zgomotul sub control:

  • Un grup pentru fiecare loc din cod. Cheia de grup este exceptions/<Class>@<file>:<line>, deci 300 de excepții identice înseamnă un singur incident, cu un contor, iar o excepție diferită înseamnă un incident separat.
  • Cel mult un claxon pe grup la 5 minute. Limitarea se face în cache-ul tău, așa că cele 299 de repetări nici nu pleacă de pe server.
  • Trimis după răspuns. În modul implicit, defer, trimiterea are loc după ce a plecat răspunsul HTTP, deci o rețea lentă nu încetinește niciodată o pagină.

Cât timp lipsește HONK_URL sau HONK_KEY, nu face nimic, așa că dezvoltarea locală și CI-ul rămân liniștite. Și nu aruncă niciodată excepții.

Poți alege alt nivel sau alt interval pentru fiecare aplicație, de exemplu un Claxon continuu cu limitare la un minut pentru un serviciu de plăți:

$exceptions->report(Honk::reportable(severity: 'blast', throttleSeconds: 60));

Restul setărilor sunt în config/honk.php. Acolo poți sări peste excepțiile previzibile, cum ar fi o plată refuzată pe care interfața o explică deja, și poți alege cum se trimit:

// config/honk.php (published by php artisan honk:install)
'exceptions' => [
    'enabled' => (bool) env('HONK_EXCEPTIONS', true),
    'severity' => 'long',
    'channel' => 'exceptions',
    'throttle' => 300,          // seconds per group
    'mode' => 'defer',          // defer (after the response), sync or queue
    'ignore' => [
        \App\Exceptions\PaymentDeclined::class,   // expected, already handled in the UI
    ],
],

Mesajele excepțiilor pleacă așa cum sunt, trunchiate cât să încapă. Nu pune date personale în ele, pentru că ar ajunge într-o notificare.

3. Acum, după răspuns sau din coadă

Aceeași alegere o ai pentru tot ce trimiți tu:

use HonkMe\Laravel\Facades\Honk;
use HonkMe\Message;

Honk::defer()->beep('New order', "{$order->email} paid {$order->total} €");   // after the response
Honk::queue(Message::make('Imported 1 204 rows')->beep()->channel('imports'));   // a queued job
Honk::loud('Disk 91%', '/var on app-01', ['groupKey' => 'disk/app-01/var']);     // right now
  • Honk::defer() rulează în același proces, după răspuns, deci nu ai nevoie de worker. Dacă procesul se oprește înainte, claxonul se pierde, ceea ce pentru majoritatea alertelor e în regulă.
  • Honk::queue() rulează într-un worker de coadă, cu reîncercări și backoff, și rezistă la reporniri. Folosește-l pentru ce trebuie neapărat să ajungă.
  • Helperele simple trimit imediat, cu reîncercări, ceea ce se potrivește pentru comenzi, joburi și sarcini programate.

Atât defer(), cât și queue() validează mesajul pe loc, deci un câmp greșit dă eroare în codul tău, nu mai târziu, într-un worker.

4. Sarcini programate

// routes/console.php
Schedule::command('backup:run')->daily()->honkOnFailure();          // problem on failure, recovery once it works again
Schedule::command('reports:send')->hourly()->honkOnSuccess();       // a beep after every successful run

honkOnFailure() trimite o problemă cu codul de ieșire și ultimele rânduri afișate, grupată pe sarcină. Când sarcina reușește din nou, trimite o revenire, dar numai după un eșec, așa că o sarcină care merge nu te deranjează niciodată. honkOnSuccess() trimite un Bip-bip după fiecare rulare reușită, pentru rapoartele despre care chiar vrei să afli.

5. Testează

Honk::fake() reține ce s-ar trimite sau s-ar pune în coadă și nu atinge niciodată rețeaua. Validează la fel ca clientul real, deci un mesaj invalid pică testul și aici:

use HonkMe\Laravel\Facades\Honk;
use HonkMe\Message;
use HonkMe\Severity;

Honk::fake();

$this->post(route('quote.store'), $data);

Honk::assertSent(fn (Message $m) => $m->groupKey === 'requests/1' && $m->severity === Severity::Light);
Honk::assertSentTimes(1);
Honk::assertNotSent(fn (Message $m) => $m->severity === Severity::Blast);
Honk::assertQueued(fn (Message $m, string $idempotencyKey) => $m->channel === 'imports');
Honk::assertNothingSent(); // also assertNothingQueued(), assertNothingOutgoing()

Ce adaugă Honk raportării din Laravel

Logul primește în continuare fiecare excepție. Honk îți trimite o notificare pentru fiecare eșec nou, pe iPhone, pe Apple Watch sau în browser, adună repetările cu un contor și le ține în același inbox cu joburile cron și serverele. Ca să tratezi altfel unele excepții fără să atingi codul, adaugă o regulă în proiect: de exemplu, trimite în rezumat exceptions/ de la o integrare gălăgioasă.

Deocamdată, Honk e disponibil doar pe bază de invitație: cere acces. Tot ce face acest ghid merge și pe planul Free.