Passed
Push — master ( 79a79c...9c574d )
by Thomas Mauro
02:27
created

DoctrineTransactionMiddleware::handleForManager()   A

Complexity

Conditions 5
Paths 20

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 16
c 1
b 0
f 0
nc 20
nop 3
dl 0
loc 26
rs 9.4222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TMV\Laminas\Messenger\Bridge\Doctrine\Middleware;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use Symfony\Component\Messenger\Envelope;
9
use Symfony\Component\Messenger\Exception\HandlerFailedException;
10
use Symfony\Component\Messenger\Middleware\StackInterface;
11
use Symfony\Component\Messenger\Stamp\HandledStamp;
12
13
/**
14
 * @final
15
 */
16
class DoctrineTransactionMiddleware extends AbstractDoctrineMiddleware
17
{
18
    protected function handleForManager(EntityManagerInterface $entityManager, Envelope $envelope, StackInterface $stack): Envelope
19
    {
20
        $entityManager->getConnection()->beginTransaction();
21
22
        $success = false;
23
        try {
24
            $envelope = $stack->next()->handle($envelope, $stack);
25
            $entityManager->flush();
26
            $entityManager->getConnection()->commit();
27
28
            $success = true;
29
30
            return $envelope;
31
        } catch (\Throwable $exception) {
32
            if ($exception instanceof HandlerFailedException) {
33
                // Remove all HandledStamp from the envelope so the retry will execute all handlers again.
34
                // When a handler fails, the queries of allegedly successful previous handlers just got rolled back.
35
                throw new HandlerFailedException($exception->getEnvelope()->withoutAll(HandledStamp::class), $exception->getNestedExceptions());
36
            }
37
38
            throw $exception;
39
        } finally {
40
            $connection = $entityManager->getConnection();
41
42
            if (! $success && $connection->isTransactionActive()) {
43
                $connection->rollBack();
44
            }
45
        }
46
    }
47
}
48