The failure transport, and retrying from the command line

A message that fails its retries has to go somewhere, and a dedicated transport plus two commands is a dead letter queue with an operator interface.

$ php bin/console messenger:failed:show
  #  Class                        Failed at             Error
  1  AppMessageSendReceipt      2019-10-14 09:12:04   SMTP timeout
  2  AppMessageRebuildReport    2019-10-14 09:40:11   Deadlock

$ php bin/console messenger:failed:show 1 -vv     # full stack trace
$ php bin/console messenger:failed:retry 1 2
$ php bin/console messenger:failed:remove 1

Being able to read the exception that killed a message without opening a log aggregator is the practical win, and it is what makes an operator willing to look at the queue at all. Retrying selectively rather than all at once matters when half the failures are a transient outage and half are a bug. The transport still needs a depth alert, because these commands only help somebody who already knows there is something to look at.