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.