Skip to content

Commit

Permalink
bug #32568 [Messenger] Fix UnrecoverableExceptionInterface handling (…
Browse files Browse the repository at this point in the history
…LanaiGrunt)

This PR was merged into the 4.3 branch.

Discussion
----------

[Messenger] Fix UnrecoverableExceptionInterface handling

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #32325
| License       | MIT
| Doc PR        | no

Fixed the handling of UnrecoverableExceptionInterface-Exceptions like suggested in [the issue thread](#32325 (comment)).

Commits
-------

49bb743 [Messenger] fixed UnrecoverableExceptionInterface handling in Worker (fixes #32325)
  • Loading branch information
fabpot committed Jul 19, 2019
2 parents 3f98846 + 49bb743 commit e44eb91
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/Symfony/Component/Messenger/Tests/WorkerTest.php
Expand Up @@ -17,6 +17,7 @@
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent;
use Symfony\Component\Messenger\Event\WorkerStoppedEvent;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Retry\RetryStrategyInterface;
Expand Down Expand Up @@ -120,6 +121,37 @@ public function testDispatchCausesRetry()
$this->assertSame(1, $receiver->getAcknowledgeCount());
}

public function testUnrecoverableMessageHandlingExceptionPreventsRetries()
{
$envelope1 = new Envelope(new DummyMessage('Unwrapped Exception'), [new SentStamp('Some\Sender', 'transport1')]);
$envelope2 = new Envelope(new DummyMessage('Wrapped Exception'), [new SentStamp('Some\Sender', 'transport1')]);

$receiver = new DummyReceiver([
[$envelope1],
[$envelope2],
]);

$bus = $this->getMockBuilder(MessageBusInterface::class)->getMock();
$bus->expects($this->at(0))->method('dispatch')->willThrowException(new UnrecoverableMessageHandlingException());
$bus->expects($this->at(1))->method('dispatch')->willThrowException(
new HandlerFailedException($envelope2, [new UnrecoverableMessageHandlingException()])
);

$retryStrategy = $this->getMockBuilder(RetryStrategyInterface::class)->getMock();
$retryStrategy->expects($this->never())->method('isRetryable')->willReturn(true);

$worker = new Worker(['transport1' => $receiver], $bus, ['transport1' => $retryStrategy]);
$worker->run([], function (?Envelope $envelope) use ($worker) {
// stop after the messages finish
if (null === $envelope) {
$worker->stop();
}
});

// message was rejected
$this->assertSame(2, $receiver->getRejectCount());
}

public function testDispatchCausesRejectWhenNoRetry()
{
$receiver = new DummyReceiver([
Expand Down
14 changes: 14 additions & 0 deletions src/Symfony/Component/Messenger/Worker.php
Expand Up @@ -191,6 +191,20 @@ private function dispatchEvent($event)

private function shouldRetry(\Throwable $e, Envelope $envelope, RetryStrategyInterface $retryStrategy): bool
{
// if ALL nested Exceptions are an instance of UnrecoverableExceptionInterface we should not retry
if ($e instanceof HandlerFailedException) {
$shouldNotRetry = true;
foreach ($e->getNestedExceptions() as $nestedException) {
if (!$nestedException instanceof UnrecoverableExceptionInterface) {
$shouldNotRetry = false;
break;
}
}
if ($shouldNotRetry) {
return false;
}
}

if ($e instanceof UnrecoverableExceptionInterface) {
return false;
}
Expand Down

0 comments on commit e44eb91

Please sign in to comment.