vendredi 12 novembre 2021

How to catch Laravel BroadcastException?

I have a Laravel 5.5 app, in which I generate events, for eg:

event(new ThingChange($thing, 'foo', 'bar'));

Those events implement ShouldBroadcast:

class ThingChange implements ShouldBroadcast  {

I'm broadcasting to Pusher channels. Broadcasting generates a queued job (I'm using the database queue driver), and the Laravel queue worker handles those jobs. The pusher config in config/broadcasting.php is standard:

'pusher' => [
    'driver'    => 'pusher',
    'key'       => env('PUSHER_APP_KEY'),
    'secret'    => env('PUSHER_APP_SECRET'),
    'app_id'    => env('PUSHER_APP_ID'),
    'options'   => [
        'cluster' => env('PUSHER_APP_CLUSTER', 'mt1'),
        'encrypted' => true,
        'useTLS'    => true
    ],
],

This all works. It has been running for years, the config is correct. It also works fine from my local dev machine. There are many questions here on SO about getting the connection to Pusher working at all, often solved by allowing unencrypted connections, or adding curl parameters (example, example, example ...) - this is not one of those questions.

However every now and then, if there are network troubles, broadcasting (unsurprisingly) fails. Last night for example there were network issues at my hosting provider's data centre, and I got a few of these exceptions in my logs:

[2021-11-11 00:22:43] production.ERROR: {"exception":"[object] (Illuminate\Broadcasting\BroadcastException(code: 0): at /path/to/vendor/laravel/framework/src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php:107)

The referenced line 107 throws that exception when Laravel could not connect to Pusher:

throw new BroadcastException(
    is_bool($response) ? 'Failed to connect to Pusher.' : $response['body']
);

This is to be expected - network was down, Laravel could not connect to Pusher. There's no way around this, and I'm not trying to magically work around network trouble.

My question is how can I catch that exception? I monitor my production logs and don't want to see these - these events are simply notifications, they are not critical, and while I'd like to log that they failed, I don't want hard ERRORs and multiple full exception traces clogging up my logs.

Trying to catch an exception when generating the event does not work of course, bcs that is not what is actually failing:

try {
    event(new ThingChange($thing, 'foo', 'bar'));
} catch (\Exception $e) {
    // Won't work, firing the event is not what fails ...
}

There is nothing to actually catch in my event class itself, it simply sets some properties for the payload, and defines the channels to broadcast on.

Is there any way to catch this, without modifying Laravel sources?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire