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

> Excepțiile din Laravel devin o notificare pe eșec cu Honk::reportable(), limitată pe excepție, plus alerte din scheduler și Honk::fake() pentru teste.

Source: https://honk-me.app/ro/ghiduri/notificari-exceptii-laravel

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](https://honk-me.app/ro/cere-acces)) și un proiect cu o cheie API: în aplicația web, deschide proiectul, apoi **Chei**.

## 1. Instalează pachetul

```sh
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.

```dotenv
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:

```sh
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`:

```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:

```php
$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:

```php
// 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:

```php
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

```php
// 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:

```php
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ă.
