I have this command
name;
}
public function getText(): string
{
return $this->text;
}
public function getUserId(): UuidInterface
{
return Uuid::fromString($this->userId);
}
}
and this handler
getName()),
new Text($command->getTe xt()),
new UserId($command->getUserId())
);
$this->todoRepository->save($todo);
}
}
this messenger.yaml
configuration
framework:
messenger:
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
# failure_transport: failed
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async:
dsn: '%env(RABBITMQ_DSN)%'
retry_strategy:
max_retries: 5
delay: 1000
multiplier: 2
max_delay: 60000
# failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'
routing:
# Route your messages to the transports
# 'App\Message\YourMessage': async
'App\Todo\Application\Command\CreateTodoCommand': async
and this services.yaml
config
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# Registra el repositorio como servicio
App\Todo\Infrastructure\Repository\DoctrineTodoRepository:
arguments:
$em: '@doctrine.orm.entity_manager'
# Registra el handler y autowire la interfaz con su implementación
App\Todo\Application\Command\CreateTodoCommandHandler:
arguments:
$todoRepository: '@App\Todo\Infrastructure\Repository\DoctrineTodoRepository'
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
But when I try t consume the queued messages I get this error
messenger.CRITICAL: Error thrown while handling message App\Todo\Application\Command\CreateTodoCommand. Removing from transport after 5 retries. Error: "No handler for message "App\Todo\Application\Command\CreateTodoCommand"." {"class":"App\\Todo\\Application\\Command\\CreateTodoCommand","retryCount":5,"error":"No handler for message \"App\\Todo\\Application\\Command\\CreateTodoCommand\".","exception":"[object] (Symfony\\Component\\Messenger\\Exception\\NoHandlerForMessageException(code: 0): No handler for message \"App\\Todo\\Application\\Command\\CreateTodoCommand\". at /var/www/html/vendor/symfony/messenger/Middleware/HandleMessageMiddleware.php:117)"} []
If I check the handlers with bin/console debug:messenger
there is no CreateTodoCommandHandler
on the list
Messenger
=========
messenger.bus.default
---------------------
The following messages can be dispatched:
----------------------------------------------------------
Symfony\Component\Process\Messenger\RunProcessMessage
handled by process.messenger.process_message_handler
Symfony\Component\Console\Messenger\RunCommandMessage
handled by console.messenger.execute_command_handler
Symfony\Component\Messenger\Message\RedispatchMessage
handled by messenger.redispatch_message_handler
----------------------------------------------------------
And I cleared cache several times
I think the config is correct, but there is no way to set the handler, there is something wrong or do I missed something?
If I use an attribute
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler]
class CreateTodoCommandHandler implements CommandHandlerInterface
then everything work correctly.
It’s a handler registration problem, and I need to set the handler without using an attribute.