1
0
mirror of https://github.com/flarum/core.git synced 2025-07-21 08:41:17 +02:00

Implement new error handling stack

This separates the error registry (mapping exception types to status
codes) from actual handling (the middleware) as well as error formatting
(Whoops, pretty error pages or JSON-API?) and reporting (log? Sentry?).

The components can be reused in different places (e.g. the API client
and the error handler middleware both need the registry to understand
all the exceptions Flarum knows how to handle), while still allowing to
change only the parts that need to change (the API stack always uses the
JSON-API formatter, and the forum stack switches between Whoops and
pretty error pages based on debug mode).

Finally, this paves the way for some planned features and extensibility:
- A console error handler can build on top of the registry.
- Extensions can register new exceptions and how to handle them.
- Extensions can change how we report exceptions (e.g. Sentry).
- We can build more pretty error pages, even different ones for
  exceptions having the same status code.
This commit is contained in:
Franz Liedke
2019-08-09 20:35:42 +02:00
parent dbbfb01e3a
commit 11e76b1965
10 changed files with 426 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Http\Middleware;
use Flarum\Foundation\ErrorHandling\Formatter;
use Flarum\Foundation\ErrorHandling\Registry;
use Flarum\Foundation\ErrorHandling\Reporter;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\MiddlewareInterface as Middleware;
use Psr\Http\Server\RequestHandlerInterface as Handler;
use Throwable;
class HandleErrors implements Middleware
{
/**
* @var Registry
*/
protected $registry;
/**
* @var Formatter
*/
protected $formatter;
/**
* @var Reporter
*/
protected $reporter;
public function __construct(Registry $registry, Formatter $formatter, Reporter $reporter)
{
$this->registry = $registry;
$this->formatter = $formatter;
$this->reporter = $reporter;
}
/**
* Catch all errors that happen during further middleware execution.
*/
public function process(Request $request, Handler $handler): Response
{
try {
return $handler->handle($request);
} catch (Throwable $e) {
$error = $this->registry->handle($e);
if ($error->shouldBeReported()) {
$this->reporter->report($error);
}
return $this->formatter->format($error, $request);
}
}
}