Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony: send failed messages via email

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.*

like image 765
writ3it Avatar asked May 28 '20 16:05

writ3it


Video Answer


1 Answers

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.

like image 141
writ3it Avatar answered Oct 27 '22 16:10

writ3it