6

I have a simple messanger config:

framework:
    messenger:
        failure_transport: failed
        transports:
            async:
                dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
                retry_strategy:
                    max_retries: 2
                    delay: 10000
            failed: 'doctrine://default?queue_name=failed'

        routing:
            someInterface: async

I would like to know about every message routed to failed transport f.e. system should send email notification to me when message is redirecting. My only idea is to periodically review messenger_messages table which contains messages stored in failed transport but imao it's not symfony-way solution. Do you know more clever solution for this feature?

I am using symfony/messenger with version 5.*

writ3it
  • 311
  • 2
  • 12

2 Answers2

10

Ultimately, I applied the solution below:

<?php
/**
 * Author: writ3it
 */

namespace App\Maintenance\Messenger;


use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\MessageBusInterface;

class FailedMessageListener implements EventSubscriberInterface
{

    /**
     * @var MessageBusInterface
     */
    private MessageBusInterface $bus;

    public function __construct(MessageBusInterface $bus)
    {
        $this->bus = $bus;
    }

    public function onMessageFailed(WorkerMessageFailedEvent $event)
    {
        if ($event->willRetry()) {
            return;
        }
        $envelope = $event->getEnvelope();
        $message = $envelope->getMessage();

        $subject = sprintf("Message added to failed transport. Message: %s", \get_class($message));
        $content = serialize($message);

        $notification = new FailedMessageNotificationEvent();
        $notification->setSubject($subject)
            ->setContent($content);
        $this->bus->dispatch($notification);
    }

    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            WorkerMessageFailedEvent::class => ['onMessageFailed', -256],
        ];
    }
}

FailedMessageNotificationEvent is a message that will be caught by my mailing handler. The FailedMessageListener class should be tagged as kernel.event_subscriber or autoconfigured.

I didn't use middleware because messenger sends messages to the failed transport directly, without middlewares.

writ3it
  • 311
  • 2
  • 12
  • 1
    Hey, thank you for your solution, could specify why -90 as priority on your event listener ? – famas23 Oct 11 '20 at 00:14
  • This should be marked as the correct answer, it will help more people in the future. – Kevin Kopf Sep 27 '21 at 03:18
  • @Famas23 Today, I have no idea :) I think, the best choice is -256 (or less) because Symfony is using range +/-256 internally and this subscriber should be executed as last. – writ3it Nov 27 '21 at 17:01
0

I don't think it's possible to do it through configuration, but you create your custom middleware and send email by yourself. https://symfony.com/doc/current/messenger.html#middleware

You can check FailedMessageProcessingMiddleware for reference https://github.com/symfony/messenger/blob/master/Middleware/FailedMessageProcessingMiddleware.php

Leprechaun
  • 759
  • 5
  • 14