diff --git a/src/Worker/Worker.php b/src/Worker/Worker.php index 8460a3ee..b75eedfb 100644 --- a/src/Worker/Worker.php +++ b/src/Worker/Worker.php @@ -42,11 +42,10 @@ public function process( $this->logger->info('Processing message #{message}.', ['message' => $messageId]); } - $handler = $this->handlerResolver->resolve($message->getType()); - $request = new ConsumeRequest($message, $queueName); - $finishHandler = new ConsumeFinalHandler($handler->handle(...)); try { + $handler = $this->handlerResolver->resolve($message->getType()); + $finishHandler = new ConsumeFinalHandler($handler->handle(...)); return $this->consumeMiddlewareDispatcher->dispatch($request, $finishHandler)->getMessage(); } catch (Throwable $exception) { $request = new FailureHandlingRequest($request->getMessage(), $exception, $request->getQueueName(), $retryProducer); diff --git a/tests/Unit/WorkerTest.php b/tests/Unit/WorkerTest.php index df648666..8d5eae30 100644 --- a/tests/Unit/WorkerTest.php +++ b/tests/Unit/WorkerTest.php @@ -10,6 +10,7 @@ use Yiisoft\Test\Support\Container\SimpleContainer; use Yiisoft\Test\Support\Log\SimpleLogger; use Yiisoft\Queue\Exception\MessageFailureException; +use Yiisoft\Queue\Message\Handler\HandlerNotFoundException; use Yiisoft\Queue\Message\Handler\HandlerResolver; use Yiisoft\Queue\Message\GenericMessage; use Yiisoft\Queue\Message\MessageInterface; @@ -108,6 +109,35 @@ public function testMessageFailureIsHandledSuccessfully(): void self::assertSame($finalMessage, $result); } + public function testUnresolvableHandlerIsHandledByFailurePipeline(): void + { + $message = new GenericMessage('unsupported', null); + $queueName = 'test-queue'; + $handlerResolver = new HandlerResolver([], new SimpleContainer()); + + $finalMessage = new GenericMessage('final', null); + /** @var FailureMiddlewareInterface&MockObject $failureMiddleware */ + $failureMiddleware = $this->createMock(FailureMiddlewareInterface::class); + $failureMiddleware + ->expects(self::once()) + ->method('processFailure') + ->with(self::callback( + static fn(FailureHandlingRequest $request): bool => $request->getException() instanceof HandlerNotFoundException, + )) + ->willReturn(new FailureHandlingRequest($finalMessage, new RuntimeException('unused'), $queueName)); + + /** @var FailureMiddlewareFactoryInterface&MockObject $failureMiddlewareFactory */ + $failureMiddlewareFactory = $this->createMock(FailureMiddlewareFactoryInterface::class); + $failureMiddlewareFactory->method('createFailureMiddleware')->willReturn($failureMiddleware); + $failureDispatcher = new FailureMiddlewareDispatcher($failureMiddlewareFactory, [$queueName => ['simple']]); + + $worker = $this->createWorkerByParams($handlerResolver, failureMiddlewareDispatcher: $failureDispatcher); + + $result = $worker->process($message, $queueName); + + self::assertSame($finalMessage, $result); + } + private function createHandlerResolver(MessageInterface $message, callable $handler): HandlerResolver { $container = new SimpleContainer();