vendor/sentry/sentry-symfony/src/EventListener/MessengerListener.php line 49
<?phpdeclare(strict_types=1);namespace Sentry\SentryBundle\EventListener;use Sentry\Event;use Sentry\EventHint;use Sentry\ExceptionMechanism;use Sentry\State\HubInterface;use Sentry\State\Scope;use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;use Symfony\Component\Messenger\Exception\DelayedMessageHandlingException;use Symfony\Component\Messenger\Exception\HandlerFailedException;use Symfony\Component\Messenger\Exception\WrappedExceptionsInterface;use Symfony\Component\Messenger\Stamp\BusNameStamp;final class MessengerListener{/*** @var HubInterface The current hub*/private $hub;/*** @var bool Whether to capture errors thrown while processing a message that* will be retried*/private $captureSoftFails;/*** @param HubInterface $hub The current hub* @param bool $captureSoftFails Whether to capture errors thrown* while processing a message that* will be retried*/public function __construct(HubInterface $hub, bool $captureSoftFails = true){$this->hub = $hub;$this->captureSoftFails = $captureSoftFails;}/*** This method is called for each message that failed to be handled.** @param WorkerMessageFailedEvent $event The event*/public function handleWorkerMessageFailedEvent(WorkerMessageFailedEvent $event): void{if (!$this->captureSoftFails && $event->willRetry()) {return;}$this->hub->withScope(function (Scope $scope) use ($event): void {$envelope = $event->getEnvelope();$exception = $event->getThrowable();$scope->setTag('messenger.receiver_name', $event->getReceiverName());$scope->setTag('messenger.message_class', \get_class($envelope->getMessage()));/** @var BusNameStamp|null $messageBusStamp */$messageBusStamp = $envelope->last(BusNameStamp::class);if (null !== $messageBusStamp) {$scope->setTag('messenger.message_bus', $messageBusStamp->getBusName());}$this->captureException($exception, $event->willRetry());});$this->flushClient();}/*** This method is called for each handled message.** @param WorkerMessageHandledEvent $event The event*/public function handleWorkerMessageHandledEvent(WorkerMessageHandledEvent $event): void{// Flush normally happens at shutdown... which only happens in the worker if it is run with a lifecycle limit// such as --time=X or --limit=Y. Flush immediately in a background worker.$this->flushClient();}/*** Creates Sentry events from the given exception.** Unpacks multiple exceptions wrapped in a HandlerFailedException and notifies* Sentry of each individual exception.** If the message will be retried the exceptions will be marked as handled* in Sentry.*/private function captureException(\Throwable $exception, bool $willRetry): void{if ($exception instanceof WrappedExceptionsInterface) {$exception = $exception->getWrappedExceptions();} elseif ($exception instanceof HandlerFailedException && method_exists($exception, 'getNestedExceptions')) {$exception = $exception->getNestedExceptions();} elseif ($exception instanceof DelayedMessageHandlingException && method_exists($exception, 'getExceptions')) {$exception = $exception->getExceptions();}if (\is_array($exception)) {foreach ($exception as $nestedException) {$this->captureException($nestedException, $willRetry);}return;}$hint = EventHint::fromArray(['exception' => $exception,'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, $willRetry),]);$this->hub->captureEvent(Event::createEvent(), $hint);}private function flushClient(): void{$client = $this->hub->getClient();if (null !== $client) {$client->flush();}}}