Middleware to catch and format errors encountered while handling the request.
- PHP >= 7.2
- A PSR-7 http library
- A PSR-15 middleware dispatcher
This package is installable and autoloadable via Composer as middlewares/error-handler.
composer require middlewares/error-handler
use Middlewares\ErrorFormatter;
use Middlewares\ErrorHandler;
use Middlewares\Utils\Dispatcher;
// Create a new ErrorHandler instance
// Any number of formatters can be added. One will be picked based on the Accept
// header of the request. If no formatter matches, the first formatter in the array
// will be used.
$errorHandler = new ErrorHandler([
new ErrorFormatter\HtmlFormatter(),
new ErrorFormatter\ImageFormatter(),
new ErrorFormatter\JsonFormatter(),
new ErrorFormatter\PlainFormatter(),
new ErrorFormatter\SvgFormatter(),
new ErrorFormatter\XmlFormatter(),
]);
// ErrorHandler should always be the first middleware in the stack!
$dispatcher = new Dispatcher([
$errorHandler,
// ...
function ($request) {
throw HttpErrorException::create(404);
}
]);
$request = $serverRequestFactory->createServerRequest('GET', '/');
$response = $dispatcher->dispatch($request);
Add the formatters to be used (instances of Middlewares\ErrorFormatter\FormatterInterface
). If no formatters are provided, use all available.
$errorHandler = new ErrorHandler([
new ErrorFormatter\HtmlFormatter(),
new ErrorFormatter\JsonFormatter()
]);
Note: If no formatter is found, the first value of the array will be used. In the example above, HtmlFormatter
.
Please note that the following snippet must go even before error-hander's middleware, which usually goes first.
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
try {
return $handler->handle($request);
} catch (Throwable $exception) {
$this->logger->critical('Uncaught {error}', [
'error' => $exception->getMessage(),
'exception' => $exception, // If you use Monolog, this is correct
]);
// leave it for the middleware
throw $exception;
}
}
This snippet might come handy when you want to customize your response in production.
class PrettyPage implements StreamFactoryInterface
{
public function createStream(string $content = ''): StreamInterface
{
return Factory::createStream('<strong>Pretty page</strong>');
}
public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
{
// This is safe as the Middleware only uses createStream()
throw new Exception('Not implemented');
}
public function createStreamFromResource($resource): StreamInterface
{
// This is safe as the Middleware only uses createStream()
throw new Exception('Not implemented');
}
}
$errorHandler = new ErrorHandler([
new HtmlFormatter(
null,
new PrettyPage,
),
]);
Please see CHANGELOG for more information about recent changes and CONTRIBUTING for contributing details.
The MIT License (MIT). Please see LICENSE for more information.