averor/sf-messenger-ext-bundle
Installation
composer require averor/sf-messenger-ext-bundle
Register the bundle in config/bundles.php (Symfony) or config/app.php (Laravel via Symfony components):
return [
// ...
averor\SfMessengerExtBundle\SfMessengerExtBundle::class => ['all' => true],
];
First Use Case: Logging Middleware
Implement a custom logger for messages by creating a service that implements averor\SfMessengerExtBundle\Middleware\LoggerInterface:
namespace App\Messenger;
use Psr\Log\LoggerInterface;
use averor\SfMessengerExtBundle\Middleware\LoggerInterface as LoggerContract;
class MessageLogger implements LoggerContract
{
public function __construct(private LoggerInterface $logger) {}
public function log(string $message, array $context = []): void
{
$this->logger->info('Messenger: ' . $message, $context);
}
}
Register it as a service and tag it with messenger.middleware in services.yaml (or Laravel's app.php bindings).
Attach Middleware
Configure the middleware in config/packages/messenger.yaml (Symfony) or config/messenger.php (Laravel):
framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
buses:
messenger.bus:
middleware:
- averor_sf_messenger_ext.logging
- averor_sf_messenger_ext.event_causation
- averor_sf_messenger_ext.exception_handling
- averor_sf_messenger_ext.identifiable_message
Command-Event Causation
Use the event_causation middleware to trace events back to their originating command:
// Command handler
public function __invoke(CreateUserCommand $command)
{
$this->bus->dispatch(new UserCreatedEvent($command->getUserId()));
// Later, in an event listener:
$event = $envelope->getStamp('command_id'); // Contains the UUID of CreateUserCommand
}
Exception Handling
Leverage exception_handling middleware to dispatch failure events:
// Configure a listener for the failure event
$dispatcher->addListener(
averor\SfMessengerExtBundle\Event\MessageFailedEvent::class,
function (MessageFailedEvent $event) {
$this->logger->error('Message failed', [
'exception' => $event->getException(),
'message' => $event->getEnvelope()->getMessage(),
]);
}
);
Identifiable Messages
Use identifiable_message to correlate messages across buses:
// Access the UUID in a middleware or handler
$uuid = $envelope->getStamp('message_id')->getUuid();
symfony/messenger via Laravel's Illuminate\Bus\Dispatcher or Illuminate\Queue\QueueManager.$envelope->add(new YourStamp('your_data'));
silencing version of exception_handling to suppress exceptions:
middleware:
- averor_sf_messenger_ext.exception_handling.silencing
Logger Implementation
The LoggerInterface in this bundle is not Psr\Log\LoggerInterface. Implement averor\SfMessengerExtBundle\Middleware\LoggerInterface explicitly.
// ❌ Wrong (will fail)
use Psr\Log\LoggerInterface;
// ✅ Correct
use averor\SfMessengerExtBundle\Middleware\LoggerInterface;
Root Cause Limitation
The event_causation middleware only stores the first command's ID as the root cause. Subsequent commands/events won’t update this stamp.
Exception Handling Quirks
exception_handling middleware does not log by default (use a listener for MessageFailedEvent).silencing version swallows exceptions—use sparingly in production.UUID Dependency
The identifiable_message middleware requires ramsey/uuid. Ensure it’s installed:
composer require ramsey/uuid
dd($envelope->all()) to inspect stamps (e.g., command_id, message_id).MessageFailedEvent listeners are registered:
$dispatcher->getListenersFor(MessageFailedEvent::class); // Should return your listener
event_causation before identifiable_message if you need the command ID in the UUID context.Custom Middleware Extend the bundle by creating your own middleware:
namespace App\Messenger;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Middleware\StackInterface;
class YourMiddleware implements MiddlewareInterface
{
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
// Add logic before/after handling
return $stack->next($envelope);
}
}
Register it in messenger.yaml:
middleware:
- App\Messenger\YourMiddleware
Override Default Middleware
Replace the bundle’s middleware with your own implementation of the same interfaces (e.g., LoggerInterface).
Stamp Extensions Add custom stamps to envelopes for your use case:
$envelope->add(new class implements StampInterface {
public function __construct(private string $data) {}
public function get(): string { return $this->data; }
});
How can I help you explore Laravel packages today?