Description
Symfony version(s) affected: 4.3.2
Description
When we run
bin/console messenger:failed:show 1 -vv
we get the following exception
Argument 1 passed to Symfony\Component\Console\Style\SymfonyStyle::writeBuffer() must be of the type string, null given, called
Exception trace:
() at /app/vendor/symfony/console/Style/SymfonyStyle.php:384
Symfony\Component\Console\Style\SymfonyStyle->writeBuffer() at /app/vendor/symfony/console/Style/SymfonyStyle.php:315
Symfony\Component\Console\Style\SymfonyStyle->writeln() at /app/vendor/symfony/messenger/Command/AbstractFailedMessagesCommand.php:104
Symfony\Component\Messenger\Command\AbstractFailedMessagesCommand->displaySingleMessage() at /app/vendor/symfony/messenger/Command/FailedMessagesShowCommand.php:121
The issue is in this line
Root of the issue is that $flattenException->getTraceAsString()
returns null
while string
is expected.
Why does it return null
?
Because when the RedeliveryStamp
is being serialized from failed transport text message to the object, it is serializing FlattenException
as well, but since there is no setter/modifier of this property, it is being skipped during serialization. It is not writable and PropertyAccessor fails.
How to reproduce
It's possible to reproduce creating a message in a failed queue with the following headers:
{
"type": "App\\Message\\CreateUnbilledUsageCharge",
"X-Message-Stamp-Symfony\\Component\\Messenger\\Stamp\\BusNameStamp": "[{\"busName\":\"messenger.bus.default\"}]",
"X-Message-Stamp-Symfony\\Component\\Messenger\\Stamp\\SentToFailureTransportStamp": "[{\"originalReceiverName\":\"unbilled\"}]",
"X-Message-Stamp-Symfony\\Component\\Messenger\\Stamp\\DelayStamp": "[{\"delay\":0}]",
"X-Message-Stamp-Symfony\\Component\\Messenger\\Stamp\\RedeliveryStamp": "[{\"retryCount\":0,\"senderClassOrAlias\":\"failed\",\"exceptionMessage\":\"Failure Message.\",\"flattenException\":{\"statusCode\":500,\"headers\":[],\"class\":\"Core\\\\Exception\\\\LogicException\",\"file\":\"/app/src/MessageHandler/CreateUnbilledUsageChargeHandler.php\",\"line\":34,\"message\":\"Failure Message.\",\"code\":0,\"previous\":null,\"allPrevious\":[],\"trace\":[],\"traceAsString\":\"TRACE AS STRING\",\"asString\":\"AS STRING\"},\"redeliveredAt\":\"2019-08-07T06:06:57+00:00\"}]",
"X-Message-Stamp-Symfony\\Component\\Messenger\\Stamp\\SentStamp": "[{\"senderClass\":\"Symfony\\\\Component\\\\Messenger\\\\Transport\\\\Doctrine\\\\DoctrineTransport\",\"senderAlias\":\"failed\"}]",
"Content-Type": "application\/json"
}
Possible Solution
- Change the way how
FlattenException
is serialized. - Cast
$flattenException->getTraceAsString()
to string like(string) $flattenException->getTraceAsString()
but this is an ugly workaround
Additional context
This screenshot proofs there is a traceAsString
before serialization:
(!) Upgrading to 4.3.3 does not solve the issue.