Skip to content

Commit 574cbf5

Browse files
committed
Add middleware to log errors
This proposes the split between logging and converting errors into response. The idea is to always add a debug message with the error that happened, which is handy for both production and development. In combination with an access log middleware we can log errors or warnings, depending on the final response status code. For production, we assume that a fingers crossed handler is used so that only errors are sent to log - with enough information. More info: - https://github.com/middlewares/access-log/blob/master/src/AccessLog.php - https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/FingersCrossedHandler.php
1 parent ce1d124 commit 574cbf5

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

src/ErrorLoggingMiddleware.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Lcobucci\ErrorHandling;
5+
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use Psr\Http\Server\MiddlewareInterface;
9+
use Psr\Http\Server\RequestHandlerInterface;
10+
use Psr\Log\LoggerInterface;
11+
use Throwable;
12+
13+
final class ErrorLoggingMiddleware implements MiddlewareInterface
14+
{
15+
/**
16+
* @var LoggerInterface
17+
*/
18+
private $logger;
19+
20+
public function __construct(LoggerInterface $logger)
21+
{
22+
$this->logger = $logger;
23+
}
24+
25+
/**
26+
* {@inheritDoc}
27+
*
28+
* @throws Throwable
29+
*/
30+
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
31+
{
32+
try {
33+
return $handler->handle($request);
34+
} catch (Throwable $error) {
35+
$this->logger->debug('Error happened while processing request', ['exception' => $error]);
36+
37+
throw $error;
38+
}
39+
}
40+
}

tests/ErrorLoggingMiddlewareTest.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Lcobucci\ErrorHandling\Tests;
5+
6+
use Lcobucci\ErrorHandling\ErrorLoggingMiddleware;
7+
use PHPUnit\Framework\MockObject\MockObject;
8+
use PHPUnit\Framework\TestCase;
9+
use Psr\Http\Server\RequestHandlerInterface;
10+
use Psr\Log\LoggerInterface;
11+
use RuntimeException;
12+
use Zend\Diactoros\Response;
13+
use Zend\Diactoros\ServerRequest;
14+
15+
/**
16+
* @coversDefaultClass \Lcobucci\ErrorHandling\ErrorLoggingMiddleware
17+
*/
18+
final class ErrorLoggingMiddlewareTest extends TestCase
19+
{
20+
/**
21+
* @var LoggerInterface&MockObject
22+
*/
23+
private $logger;
24+
25+
/**
26+
* @before
27+
*/
28+
public function createLogger(): void
29+
{
30+
$this->logger = $this->createMock(LoggerInterface::class);
31+
}
32+
33+
/**
34+
* @test
35+
*
36+
* @covers ::__construct
37+
* @covers ::process
38+
*/
39+
public function processShouldLogAllExceptionsOrErrorsThatHappenedDuringRequestHandling(): void
40+
{
41+
$error = new RuntimeException('Testing');
42+
43+
$this->logger->expects(self::once())
44+
->method('debug')
45+
->with('Error happened while processing request', ['exception' => $error]);
46+
47+
$handler = $this->createMock(RequestHandlerInterface::class);
48+
$handler->method('handle')->willThrowException($error);
49+
50+
$middleware = new ErrorLoggingMiddleware($this->logger);
51+
52+
$this->expectExceptionObject($error);
53+
$middleware->process(new ServerRequest(), $handler);
54+
}
55+
56+
/**
57+
* @test
58+
*
59+
* @covers ::__construct
60+
* @covers ::process
61+
*/
62+
public function processShouldReturnResponseWhenEverythingIsAlright(): void
63+
{
64+
$this->logger->expects(self::never())->method('debug');
65+
66+
$response = new Response();
67+
68+
$handler = $this->createMock(RequestHandlerInterface::class);
69+
$handler->method('handle')->willReturn($response);
70+
71+
$middleware = new ErrorLoggingMiddleware($this->logger);
72+
73+
self::assertSame($response, $middleware->process(new ServerRequest(), $handler));
74+
}
75+
}

0 commit comments

Comments
 (0)