/**
  * @param TransportReceiveContext $context
  * @param callable                $next
  */
 public function invoke($context, callable $next)
 {
     try {
         $next();
     } catch (CriticalErrorException $e) {
         // all hope is gone
         throw $e;
     } catch (\Exception $e) {
         $incomingMessage = $context->getMessage();
         $incomingMessage->revertToOriginalBodyIfNeeded();
         $exceptionHeaders = $this->exceptionConverter->convert($e, $this->localAddress);
         $newHeaders = array_merge($incomingMessage->getHeaders(), $exceptionHeaders);
         $outgoingMessage = new OutgoingPhysicalMessage($incomingMessage->getMessageId(), $newHeaders, $incomingMessage->getBody());
         $dispatchContext = $this->contextFactory->createDispatchContext([new TransportOperation($outgoingMessage, new UnicastAddressTag($this->errorQueueAddress))], $context);
         $this->dispatchPipeline->invoke($dispatchContext);
     }
 }
 /**
  * @param TransportReceiveContext $context
  * @param callable                $next
  *
  * @throws \Exception
  */
 public function invoke($context, callable $next)
 {
     try {
         $next();
     } catch (CriticalErrorException $e) {
         // no retry for critical errors
         throw $e;
     } catch (MessageDeserializationException $e) {
         // no retry for invalid messages
         throw $e;
     } catch (\Exception $e) {
         $messageId = $context->getMessageId();
         $numberOfRetries = $this->retryStorage->getFailuresForMessage($messageId);
         if ($this->retryPolicy->shouldGiveUp($numberOfRetries)) {
             $this->retryStorage->clearFailuresForMessage($messageId);
             $message = $context->getMessage();
             $message->setHeader(FirstLevelRetryHeaderTypeEnum::RETRIES, $numberOfRetries);
             throw $e;
         }
         $this->retryStorage->incrementFailuresForMessage($context->getMessageId());
         $context->abortReceiveOperation();
     }
 }