Skip to content
Advertisement

Laravel graceful end event-listener within a request

Within my controller I am creating a message which then fires an event after a successful message create:

public function store(Conversation $conversation, Request $request)
{
    $message = Message::create(...)
       
    event(new MessageCreated($message));

    return response([
        'message' => $message,
    ]);
}

Now the event has a few listeners on it, one of which checks if it can send a message over external provider. What I am doing within a listener is throwing an error if something fails.

I don’t understand how could an exception trace of a listener come as a response to POST /message request since I am returning right after an event. Following on that, I would like to return a custom response if something fails so I can fail gracefully, and surely enough this works:

try {
    event(new MessageCreated($message));
} catch (Exception $e) {
    return 'failed';
}

But…why does it work? It seems very wrong. Is there a more standard way to handle this?

Advertisement

Answer

By your code I assume this is not an queued event. In that case the execution on this event is not async but sync.

By that I mean that execution goes all the was to your event(new MessageCreated($message)); then “summons” (so to speak) a piece of code (in your case MessageCreated($message)) which then throws an exception. However that exception is caught in your handler (AppExceptionsHandler) and returned as a 500 server error.

You can catch those exceptions there and ignore them or you can go with what is written in the docs https://laravel.com/docs/7.x/events#defining-listeners

Stopping The Propagation Of An Event

Sometimes, you may wish to stop the propagation of an event to other listeners. You may do so by returning false from your listener’s handle method.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement