diff --git a/framework/core/src/Foundation/ErrorHandling/HandledError.php b/framework/core/src/Foundation/ErrorHandling/HandledError.php index 738ba6da5..55b57d5d7 100644 --- a/framework/core/src/Foundation/ErrorHandling/HandledError.php +++ b/framework/core/src/Foundation/ErrorHandling/HandledError.php @@ -13,6 +13,13 @@ namespace Flarum\Foundation\ErrorHandling; use Throwable; +/** + * An error that was caught / interpreted by Flarum's error handling stack. + * + * Most importantly, such an error has a "type" (which is used to look up + * translated error messages and views to render pretty HTML pages) and an + * associated HTTP status code for used in rendering HTTP error responses. + */ class HandledError { private $error; diff --git a/framework/core/src/Foundation/ErrorHandling/HttpFormatter.php b/framework/core/src/Foundation/ErrorHandling/HttpFormatter.php index 27a383aed..92473aceb 100644 --- a/framework/core/src/Foundation/ErrorHandling/HttpFormatter.php +++ b/framework/core/src/Foundation/ErrorHandling/HttpFormatter.php @@ -16,5 +16,16 @@ use Psr\Http\Message\ServerRequestInterface as Request; interface HttpFormatter { + /** + * Create an HTTP Response to represent the error we are handling. + * + * This method receives the error that was caught by Flarum's error handling + * stack, along with the current HTTP request instance. It should return an + * HTTP response that explains or represents what went wrong. + * + * @param HandledError $error + * @param Request $request + * @return Response + */ public function format(HandledError $error, Request $request): Response; } diff --git a/framework/core/src/Foundation/ErrorHandling/JsonApiFormatter.php b/framework/core/src/Foundation/ErrorHandling/JsonApiFormatter.php index 87e1921ec..bebdf9d15 100644 --- a/framework/core/src/Foundation/ErrorHandling/JsonApiFormatter.php +++ b/framework/core/src/Foundation/ErrorHandling/JsonApiFormatter.php @@ -16,6 +16,11 @@ use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Tobscure\JsonApi\Document; +/** + * A formatter to render exceptions as valid {JSON:API} error object. + * + * See https://jsonapi.org/format/1.0/#errors. + */ class JsonApiFormatter implements HttpFormatter { public function format(HandledError $error, Request $request): Response diff --git a/framework/core/src/Foundation/ErrorHandling/LogReporter.php b/framework/core/src/Foundation/ErrorHandling/LogReporter.php index edff300d1..b9344c5c8 100644 --- a/framework/core/src/Foundation/ErrorHandling/LogReporter.php +++ b/framework/core/src/Foundation/ErrorHandling/LogReporter.php @@ -13,6 +13,9 @@ namespace Flarum\Foundation\ErrorHandling; use Psr\Log\LoggerInterface; +/** + * Log caught exceptions to a PSR-3 logger instance. + */ class LogReporter implements Reporter { /** diff --git a/framework/core/src/Foundation/ErrorHandling/Registry.php b/framework/core/src/Foundation/ErrorHandling/Registry.php index 45ed5c4ec..d5b0bb9fe 100644 --- a/framework/core/src/Foundation/ErrorHandling/Registry.php +++ b/framework/core/src/Foundation/ErrorHandling/Registry.php @@ -14,6 +14,13 @@ namespace Flarum\Foundation\ErrorHandling; use Flarum\Foundation\KnownError; use Throwable; +/** + * Flarum's central registry of known error types. + * + * It knows how to deal with errors raised both within Flarum's core and outside + * of it, map them to error "types" and how to determine appropriate HTTP status + * codes for them. + */ class Registry { private $statusMap; @@ -27,6 +34,18 @@ class Registry $this->handlerMap = $handlerMap; } + /** + * Map exceptions to handled errors. + * + * This can map internal ({@see \Flarum\Foundation\KnownError}) as well as + * external exceptions (any classes inheriting from \Throwable) to instances + * of {@see \Flarum\Foundation\ErrorHandling\HandledError}. + * + * Even for unknown exceptions, a generic fallback will always be returned. + * + * @param Throwable $error + * @return HandledError + */ public function handle(Throwable $error): HandledError { return $this->handleKnownTypes($error) diff --git a/framework/core/src/Foundation/ErrorHandling/ViewFormatter.php b/framework/core/src/Foundation/ErrorHandling/ViewFormatter.php index 12664bbd2..d40ca2ca4 100644 --- a/framework/core/src/Foundation/ErrorHandling/ViewFormatter.php +++ b/framework/core/src/Foundation/ErrorHandling/ViewFormatter.php @@ -18,6 +18,17 @@ use Psr\Http\Message\ServerRequestInterface as Request; use Symfony\Component\Translation\TranslatorInterface; use Zend\Diactoros\Response\HtmlResponse; +/** + * A formatter for turning caught exceptions into "pretty" HTML error pages. + * + * For certain known error types, we display pages with dedicated information + * relevant to this class of error, e.g. a page with a search form for HTTP 404 + * "Not Found" errors. We look for templates in the `views/error` directory. + * + * If no specific template exists, a generic "Something went wrong" page will be + * displayed, optionally enriched with a more specific error message if found in + * the translation files. + */ class ViewFormatter implements HttpFormatter { /** diff --git a/framework/core/src/Foundation/ErrorHandling/WhoopsFormatter.php b/framework/core/src/Foundation/ErrorHandling/WhoopsFormatter.php index 549ea8a0a..7f2d26456 100644 --- a/framework/core/src/Foundation/ErrorHandling/WhoopsFormatter.php +++ b/framework/core/src/Foundation/ErrorHandling/WhoopsFormatter.php @@ -15,6 +15,15 @@ use Franzl\Middleware\Whoops\WhoopsRunner; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +/** + * Handle errors using the Whoops error handler for debugging. + * + * Proper status codes for all known error types are returned. In addition, + * content negotiation is performed to return proper responses in various + * environments such as HTML frontends or API backends. + * + * Should only be used in debug mode (because Whoops may expose sensitive data). + */ class WhoopsFormatter implements HttpFormatter { public function format(HandledError $error, Request $request): Response diff --git a/framework/core/src/Http/Middleware/HandleErrors.php b/framework/core/src/Http/Middleware/HandleErrors.php index 470c379fd..d423d653c 100644 --- a/framework/core/src/Http/Middleware/HandleErrors.php +++ b/framework/core/src/Http/Middleware/HandleErrors.php @@ -19,6 +19,13 @@ use Psr\Http\Server\MiddlewareInterface as Middleware; use Psr\Http\Server\RequestHandlerInterface as Handler; use Throwable; +/** + * Catch exceptions thrown in a PSR-15 middleware stack and handle them safely. + * + * All errors will be rendered using the provided formatter. In addition, + * unknown errors will be passed on to one or multiple + * {@see \Flarum\Foundation\ErrorHandling\Reporter} instances. + */ class HandleErrors implements Middleware { /**