-
Notifications
You must be signed in to change notification settings - Fork 438
Description
I'm using the Symfony bundle. I start my consumer using bin/console enqueue/consume and sure enough it works just fine.
However if one of the consumed messages causes an exception, the consumer freezes without even writing anything to console or log - the exception is nowhere to be seen.
I used xdebug to find out what caused it and I believe the reason is that Symfony/Console runs into an infinite loop while trying to print the exception.
The reason why that happens is this code in your bundle:
enqueue-dev/pkg/enqueue/Consumption/QueueConsumer.php
Lines 320 to 331 in 499360e
| $wrapper = $e; | |
| while ($prev = $wrapper->getPrevious()) { | |
| if ($exception === $wrapper = $prev) { | |
| throw $e; | |
| } | |
| } | |
| if ($exception !== $wrapper) { | |
| $prev = new \ReflectionProperty('Exception', 'previous'); | |
| $prev->setAccessible(true); | |
| $prev->setValue($wrapper, $exception); | |
| } |
It effectively creates a pair of exceptions where each has set the other one as the previous:
$e->getPrevious()->getPrevious() === $e // true(or a longer chain of exceptions where the last one has the first one as previous - still effectively a cycle of exceptions)
I don't quite understand what is the idea behind this but obviously when an error handler tries to dump the exception chain this causes an infinite loop because ->getPrevious() never returns null.
Can you explain what the code in QueueConsumer::onProcessorException() is supposed to do? I'm quite sure this isn't intentional. When I remove the code I linked above, everything works as expected.