From 63328e56e1ef3d86edf95136213f55723543cd9e Mon Sep 17 00:00:00 2001 From: Marc-Alexander Prowe Date: Wed, 27 Sep 2023 19:27:49 +0200 Subject: [PATCH 1/2] Pass ErrorHandler to the RouteHandler. --- src/App.php | 6 ++++-- src/Io/RouteHandler.php | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/App.php b/src/App.php index c746ceb..7e67e32 100644 --- a/src/App.php +++ b/src/App.php @@ -101,8 +101,10 @@ public function __construct(...$middleware) if ($needsAccessLog instanceof Container) { \array_unshift($handlers, $needsAccessLog->getAccessLogHandler()); } - - $this->router = new RouteHandler($container); + $errorHandler = \array_reduce($handlers, function ($carry, $handler) { + return $carry ?? ($handler instanceof ErrorHandler ? $handler : null); + }); + $this->router = new RouteHandler($container, $errorHandler); $handlers[] = $this->router; $this->handler = new MiddlewareHandler($handlers); $this->sapi = \PHP_SAPI === 'cli' ? new ReactiveHandler($container->getEnv('X_LISTEN')) : new SapiHandler(); diff --git a/src/Io/RouteHandler.php b/src/Io/RouteHandler.php index 2b0cf1c..2bd080e 100644 --- a/src/Io/RouteHandler.php +++ b/src/Io/RouteHandler.php @@ -30,10 +30,10 @@ class RouteHandler /** @var Container */ private $container; - public function __construct(Container $container = null) + public function __construct(Container $container = null, ErrorHandler $errorHandler = null) { $this->routeCollector = new RouteCollector(new RouteParser(), new RouteGenerator()); - $this->errorHandler = new ErrorHandler(); + $this->errorHandler = $errorHandler ?? new ErrorHandler(); $this->container = $container ?? new Container(); } From 70051b9106221ef68621123499057966f783f615 Mon Sep 17 00:00:00 2001 From: Marc-Alexander Prowe Date: Fri, 29 Sep 2023 17:45:01 +0200 Subject: [PATCH 2/2] Test error handler passed from app is used in route handler. --- tests/AppTest.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/AppTest.php b/tests/AppTest.php index d59955d..d5bcab0 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -1649,6 +1649,32 @@ public function testInvokeWithMatchingRouteReturnsInternalServerErrorResponseWhe $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got null.

\n", (string) $response->getBody()); } + public function testRouteHandlerUsesErrorHandlerPassedFromApp(): void + { + $errorHandler = $this->createMock(ErrorHandler::class); + $errorHandler->expects($this->once()) + ->method('requestNotFound') + ->willReturn(Response::json(['error' => 'Not Found'])->withStatus(404)); + $errorHandler->method('__invoke') + ->will( + $this->returnCallback( + function (ServerRequestInterface $request, callable $next) { + return $next($request); + } + ) + ); + $app = $this->createAppWithoutLogger($errorHandler); + + $request = new ServerRequest('GET', 'http://localhost/invalid'); + + $response = $app($request); + assert($response instanceof ResponseInterface); + + $this->assertEquals(404, $response->getStatusCode()); + $this->assertEquals('application/json', $response->getHeaderLine('Content-Type')); + $this->assertStringMatchesFormat("{%a}", (string) $response->getBody()); + } + private function createAppWithoutLogger(callable ...$middleware): App { $app = new App(...$middleware);