I'm using the Symfony Messenger component in a Symfony 4.4 application. I'm processing the messages async through RabbitMQ and storing the failed ones in a database through the Doctrine transport.
And this is the messenger config:
framework: messenger: failure_transport: failed buses: command_bus: middleware: - doctrine_ping_connection transports: failed: 'doctrine://default?queue_name=failed' async_priority_high: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' retry_strategy: delay: 2000 max_retries: 5 multiplier: 2 options: exchange: name: high queues: messages_high: ~ async_priority_low: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' retry_strategy: delay: 3000 max_retries: 3 multiplier: 2 options: exchange: name: low queues: messages_low: ~ routing:'App\SampleMessageButHighPriority': async_priority_high'App\SampleMessageInterface': async_priority_low'App\OtherMessage': async_priority_low
Here is a sample handler that handler messages imlpementing the SampleMessageInterface
interface.
final class SampleMessageHandler implements MessageHandlerInterface{ private ProjectRepository $projectRepository; public function __construct(ProjectRepository $projectRepository) { $this->projectRepository = $projectRepository; } public function __invoke(SampleMessageInterface $message): void { $project = $this->projectRepository->find($message->getProjectId()->toString()); if ($project === null) { return; } $this->someProcessor->__invoke($project); }}
Everything is working before facing any message failure. The problem starts showing after failing when trying to retry or show the failed messages. Let's try the php bin/console messenger:failed:show
command:
Result:
In PhpSerializer.php line 64: Cannot instantiate interface App\SampleMessageInterface
I guess that Symfony needs to unserialize the failed message, previously serialized and stored in the database, but can't do it because it's an interface.
How can I solve this? Is there any way to serialize the failed messages using the class implementation, not the interface?