Den
Den

Reputation: 75

No handler for message "App\Message\Event\EventMessage". (tow separated message buses)

github repo: https://github.com/00if23/symfony-messenger-testcase

Just run bin/console testcase

I need tow separated message buses to use it with different (not compatible) middleware sets. I have two sets of message, middleware and handler class:

CommandMessage -> CommandMessageMiddlware -> CommandMessageHandler
EventMessage -> EventMessageMiddlware -> EventMessageHandler

I make config/packages/messenger.yaml

framework:
    messenger:
        default_bus: command.bus
        buses:
            event.bus:
                middleware:
                    - App\Middleware\EventMessageMiddlware
            command.bus:
                middleware:
                    - App\Middleware\CommandMessageMiddlware

And add to config/services.yaml


services
    ...
    ...
    App\Message\:
        resource: '../src/Message'
        autoconfigure: false

    App\MessageHandler\:
        resource: '../src/MessageHandler'
        autoconfigure: false

    App\MessageHandler\Event\EventMessageHandler:
        autoconfigure: false
        tags: 
            -   name: messenger.message_handler
                bus: event.bus
                handles: App\Message\Event\EventMessage


    App\MessageHandler\Command\CommandMessageHandler:
        autoconfigure: false
        tags: 
            -   name: messenger.message_handler
                bus: command.bus
                handles: App\Message\Command\CommandMessage

The result is:

        // works as expected with CommandMessageMiddlware
        // on default "command.bus"
        $this->bus->dispatch(new CommandMessage()); 

        // BUT! There I have 'No handler for message "App\Message\Event\EventMessage"' 
        $this->bus->dispatch(new EventMessage());

Every time I dispatch any event on non-default message bus, then I have error "No handler for message XXX"

This is messager:debug command:

Messenger
=========

command.bus
-----------

 The following messages can be dispatched:

 ------------------------------------------------------------------------------------------------------ 
  Messages for COMMAND bus                                                                              
  App\Message\Command\CommandMessage                                                      
      handled by App\MessageHandler\Command\CommandMessageHandler (when bus=command.bus)                                                                                             
 ------------------------------------------------------------------------------------------------------ 

event.bus
---------

 The following messages can be dispatched:

 ---------------------------------------------------------------------------------------------------- 
  Messages for EVENT bus                                                                             
  App\Message\Event\EventMessage                                                    
      handled by App\MessageHandler\Event\EventMessageHandler (when bus=event.bus)  
 ---------------------------------------------------------------------------------------------------- 

Upvotes: 0

Views: 119

Answers (1)

Christoph
Christoph

Reputation: 692

The MessageBusInterface that you inject in your command is the default message bus of your application. In your case it is the command.bus, which is the reason why dispatching the CommandMessage works in your example.

The EventMessage must be dispatched via the event message bus. You have to inject the corresponding MessageBusInterface, and use it for dispatching.

There are multiple ways to inject the different interface. Symfony conveniently binds your buses to variable names. If you inject MessageBusInterface $eventBus you will automatically get the event bus service. MessageBusInterface $commandBus or MessageBusInterface $bus (as the command bus is the default) will give you the command bus. You can check bin/console debug:container for more details.

I updated your command like that:

#[AsCommand(
    name: 'testcase',
)]
class TestCaseCommand extends Command
{
    public function __construct(
        private readonly MessageBusInterface $commandBus,
        private readonly MessageBusInterface $eventBus
    )
    {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        $this->commandBus->dispatch(new CommandMessage());
        $this->eventBus->dispatch(new EventMessage());

        $io->success('Done');

        return Command::SUCCESS;
    }
}

And get the following output:

➜  symfony-messenger-testcase git:(main) ✗ bin/console testcase                           
App\Middleware\Command\CommandMiddleware in effect
App\MessageHandler\Command\CommandMessageHandler in effect
App\Middleware\Event\EventMiddleware in effect
App\MessageHandler\Event\EventMessageHandler in effect

                                                                                                                        
 [OK] Done                                                                                                                                                                                                                                      

Upvotes: 1

Related Questions