Exceptions.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php declare(strict_types=1);
  2. /**
  3. * @package Grav\Framework\RequestHandler
  4. *
  5. * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Framework\RequestHandler\Middlewares;
  9. use Grav\Common\Data\ValidationException;
  10. use Grav\Common\Debugger;
  11. use Grav\Common\Grav;
  12. use Grav\Framework\Psr7\Response;
  13. use JsonException;
  14. use JsonSerializable;
  15. use Psr\Http\Message\ResponseInterface;
  16. use Psr\Http\Message\ServerRequestInterface;
  17. use Psr\Http\Server\MiddlewareInterface;
  18. use Psr\Http\Server\RequestHandlerInterface;
  19. use Throwable;
  20. use function get_class;
  21. /**
  22. * Class Exceptions
  23. * @package Grav\Framework\RequestHandler\Middlewares
  24. */
  25. class Exceptions implements MiddlewareInterface
  26. {
  27. /**
  28. * @param ServerRequestInterface $request
  29. * @param RequestHandlerInterface $handler
  30. * @return ResponseInterface
  31. * @throws JsonException
  32. */
  33. public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
  34. {
  35. try {
  36. return $handler->handle($request);
  37. } catch (Throwable $exception) {
  38. $code = $exception->getCode();
  39. if ($exception instanceof ValidationException) {
  40. $message = $exception->getMessage();
  41. } else {
  42. $message = htmlspecialchars($exception->getMessage(), ENT_QUOTES | ENT_HTML5, 'UTF-8');
  43. }
  44. $extra = $exception instanceof JsonSerializable ? $exception->jsonSerialize() : [];
  45. $response = [
  46. 'code' => $code,
  47. 'status' => 'error',
  48. 'message' => $message,
  49. 'error' => [
  50. 'code' => $code,
  51. 'message' => $message,
  52. ] + $extra
  53. ];
  54. /** @var Debugger $debugger */
  55. $debugger = Grav::instance()['debugger'];
  56. if ($debugger->enabled()) {
  57. $response['error'] += [
  58. 'type' => get_class($exception),
  59. 'file' => $exception->getFile(),
  60. 'line' => $exception->getLine(),
  61. 'trace' => explode("\n", $exception->getTraceAsString()),
  62. ];
  63. }
  64. /** @var string $json */
  65. $json = json_encode($response, JSON_THROW_ON_ERROR);
  66. return new Response($code ?: 500, ['Content-Type' => 'application/json'], $json);
  67. }
  68. }
  69. }