for testing and deploying your application
for finding and fixing issues
for empowering human code reviews
<?php
declare(strict_types=1);
namespace TMV\Messenger\Middleware;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\Middleware\StackInterface;
use Symfony\Component\Messenger\Stamp\HandledStamp;
use Throwable;
class DoctrineTransactionMiddleware extends AbstractDoctrineMiddleware
{
protected function handleForManager(
EntityManagerInterface $entityManager,
Envelope $envelope,
StackInterface $stack
): Envelope {
$entityManager->getConnection()->beginTransaction();
try {
$envelope = $stack->next()->handle($envelope, $stack);
$entityManager->flush();
$entityManager->getConnection()->commit();
return $envelope;
} 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;