diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php index ad0d87b97c..62f0bac51d 100644 --- a/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php +++ b/src/Symfony/Bridge/Doctrine/Messenger/DoctrineTransactionMiddleware.php @@ -13,9 +13,11 @@ namespace Symfony\Bridge\Doctrine\Messenger; use Doctrine\Common\Persistence\ManagerRegistry; use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Exception\HandlerFailedException; use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException; use Symfony\Component\Messenger\Middleware\MiddlewareInterface; use Symfony\Component\Messenger\Middleware\StackInterface; +use Symfony\Component\Messenger\Stamp\HandledStamp; /** * Wraps all handlers in a single doctrine transaction. @@ -56,6 +58,12 @@ class DoctrineTransactionMiddleware implements MiddlewareInterface } catch (\Throwable $exception) { $entityManager->getConnection()->rollBack(); + if ($exception instanceof HandlerFailedException) { + // Remove all HandledStamp from the envelope so the retry will execute all handlers again. + // When a handler fails, the queries of allegedly successful previous handlers just got rolled back. + throw new HandlerFailedException($exception->getEnvelope()->withoutAll(HandledStamp::class), $exception->getNestedExceptions()); + } + throw $exception; } }