diff --git a/src/Controller/MessengerMonitorController.php b/src/Controller/MessengerMonitorController.php index a734a63..5be0223 100644 --- a/src/Controller/MessengerMonitorController.php +++ b/src/Controller/MessengerMonitorController.php @@ -18,6 +18,11 @@ use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\Messenger\Message\RedispatchMessage; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Messenger\Stamp\DelayStamp; +use Symfony\Component\Messenger\Stamp\ErrorDetailsStamp; +use Symfony\Component\Messenger\Stamp\RedeliveryStamp; +use Symfony\Component\Messenger\Stamp\SentToFailureTransportStamp; +use Symfony\Component\Messenger\Stamp\TransportMessageIdStamp; use Symfony\Component\Messenger\Stamp\TransportNamesStamp; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Scheduler\Generator\MessageContext; @@ -26,6 +31,7 @@ use Zenstruck\Messenger\Monitor\History\Period; use Zenstruck\Messenger\Monitor\History\Specification; use Zenstruck\Messenger\Monitor\Schedules; +use Zenstruck\Messenger\Monitor\Stamp\MonitorStamp; use Zenstruck\Messenger\Monitor\Stamp\TagStamp; use Zenstruck\Messenger\Monitor\Twig\ViewHelper; @@ -147,6 +153,33 @@ public function removeTransportMessage( return $this->redirectToRoute('zenstruck_messenger_monitor_transport', ['name' => $name]); } + #[Route('/transport/{name}/{id}/retry', name: 'zenstruck_messenger_monitor_transport_retry', methods: 'POST')] + public function retryFailedMessage( + string $name, + string $id, + Request $request, + ViewHelper $helper, + MessageBusInterface $bus, + ): Response { + if (!$this->isCsrfTokenValid(\sprintf('retry-%s-%s', $id, $name), $request->request->getString('_token'))) { + throw new HttpException(419, 'Invalid CSRF token.'); + } + + $transport = $helper->transports->get($name); + $message = $transport->find($id) ?? throw $this->createNotFoundException('Message not found.'); + $originalTransportName = $message->envelope()->last(SentToFailureTransportStamp::class)?->getOriginalReceiverName() ?? throw $this->createNotFoundException('Original transport not found.'); + + $bus->dispatch($message->envelope(), [ + new TagStamp('retry'), + new TagStamp('manual'), + ]); + $transport->get()->reject($message->envelope()); + + $this->addFlash('success', \sprintf('Retrying message "%s" on transport "%s".', $message->message()->shortName(), $originalTransportName)); + + return $this->redirectToRoute('zenstruck_messenger_monitor_transport', ['name' => $name]); + } + #[Route('/schedule/{name}', name: 'zenstruck_messenger_monitor_schedule', defaults: ['name' => null])] public function schedules( ViewHelper $helper, diff --git a/templates/transport.html.twig b/templates/transport.html.twig index 15235df..03b7bcd 100644 --- a/templates/transport.html.twig +++ b/templates/transport.html.twig @@ -96,11 +96,17 @@ {% endif %} {% endif %} -