laracoft's avatar

How to have multiple handlers for events?

In one of package's service provider, I have

Event::listen(MessageSending::class, MyHandler::class);

Then I added https://github.com/jdavidbakr/mail-tracker which also tries to listen to MessageSending (https://github.com/jdavidbakr/mail-tracker/blob/96244f621f1201385a2645152cabb414b2a7fde3/src/MailTrackerServiceProvider.php#L36), however, only MyHandler is called.

How do I make both handlers run on the event?

0 likes
10 replies
Glukinho's avatar

Closure listeners are defined with a closure alone, no need to have MessageSending::class as first parameter:

Event::listen(function (MessageSending $event) {
    $tracker = new MailTracker;
    $tracker->messageSending($event);
});
laracoft's avatar

Are you suggesting his code does not work? Because it does (if I remove my listener).

Glukinho's avatar

Sorry, my suggestion was wrong, I misread your post.

What php artisan event:list shows? Do you see both listeners for MessageSending event there?

  App\Events\TestEvent ...........................
  ⇂ Closure at: /app/Providers/AppServiceProvider.php:111
  ⇂ App\Jobs\TestJob (ShouldQueue)
  ⇂ App\Actions\TestAction
  ⇂ App\Jobs\TestJobNew (ShouldQueue)
laracoft's avatar

I see 2 handlers for Illuminate\Mail\Events\MessageSending, yet only 1 runs (the first one)

The 1st one is a class, 2nd is a closure.

Glukinho's avatar

How do you know the second listener is not run?

What if you apply your own test closure (with simple Log::debug('test listener');) as third listener - will it run and write to log?

Did you run php artisan optimize:clear or event:clear to flush events cache?

laracoft's avatar

Because I step debug and also there are no tracked links in the email (second listener's job)

martinbean's avatar

@laracoft You can define multiple listeners for an event by passing an array as the second parameter:

Event::listen(MessageSending::class, [
    ListenerOne::class,
    ListenerTwo::class,
]);
laracoft's avatar

Thanks, but the docs say I can call it multiple times, and it doesn't work as described in my case. (I can't call an array because it is 2 separate service providers)

laracoft's avatar
laracoft
OP
Best Answer
Level 27

After more debugging, I found the issue: for a handler's handle(), it must return null. Anything else will cause the next handler not to run.

1 like

Please or to participate in this conversation.