Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
99 lines (81 sloc) 3.14 KB
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Messenger\Middleware;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\Exception\NoHandlerForMessageException;
use Symfony\Component\Messenger\Handler\HandlersLocatorInterface;
use Symfony\Component\Messenger\Stamp\HandledStamp;
/**
* @author Samuel Roze <samuel.roze@gmail.com>
*
* @experimental in 4.2
*/
class HandleMessageMiddleware implements MiddlewareInterface
{
use LoggerAwareTrait;
private $handlersLocator;
private $allowNoHandlers;
public function __construct(HandlersLocatorInterface $handlersLocator, bool $allowNoHandlers = false)
{
$this->handlersLocator = $handlersLocator;
$this->allowNoHandlers = $allowNoHandlers;
$this->logger = new NullLogger();
}
/**
* {@inheritdoc}
*
* @throws NoHandlerForMessageException When no handler is found and $allowNoHandlers is false
*/
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
$handler = null;
$message = $envelope->getMessage();
$context = [
'message' => $message,
'class' => \get_class($message),
];
$exceptions = [];
foreach ($this->handlersLocator->getHandlers($envelope) as $alias => $handler) {
$alias = \is_string($alias) ? $alias : null;
if ($this->messageHasAlreadyBeenHandled($envelope, $handler, $alias)) {
continue;
}
try {
$handledStamp = HandledStamp::fromCallable($handler, $handler($message), $alias);
$envelope = $envelope->with($handledStamp);
$this->logger->info('Message "{class}" handled by "{handler}"', $context + ['handler' => $handledStamp->getCallableName()]);
} catch (\Throwable $e) {
$exceptions[] = $e;
}
}
if (null === $handler) {
if (!$this->allowNoHandlers) {
throw new NoHandlerForMessageException(sprintf('No handler for message "%s".', $context['class']));
}
$this->logger->info('No handler for message "{class}"', $context);
}
if (\count($exceptions)) {
throw new HandlerFailedException($envelope, $exceptions);
}
return $stack->next()->handle($envelope, $stack);
}
private function messageHasAlreadyBeenHandled(Envelope $envelope, callable $handler, ?string $alias): bool
{
$some = array_filter($envelope
->all(HandledStamp::class), function (HandledStamp $stamp) use ($handler, $alias) {
return $stamp->getCallableName() === HandledStamp::getNameFromCallable($handler) &&
$stamp->getHandlerAlias() === $alias;
});
return \count($some) > 0;
}
}
You can’t perform that action at this time.