Как отмечают многие, страницы ошибок генерируются только для среды dev
и test
. В среде prod
, которую вы должны использовать в своей действующей системе, отобразится общая страница 404, которую вы можете настроить.
Система, отвечающая за отображение подробной страницы ошибки в процессе разработки или обычной 404page in production - это цикл событий Symfony, точнее, событие kernel.exception
, которое прослушивается, а затем любые неперехваченные ошибки и исключения будут преобразованы в ответ страницы с ошибкой. Поскольку вы пишете API, возможно, вы захотите зарегистрировать свой собственный слушатель и вернуть ответ JSON вместо обычного HTML.
Подписчик события для этого может выглядеть примерно так:
<?php declare(strict_types = 1);
namespace App\Api\Response;
use Exception;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\KernelEvents;
final class ExceptionToJsonResponseSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
KernelEvents::EXCEPTION => 'onKernelException',
];
}
public function onKernelException(GetResponseForExceptionEvent $event): void
{
// Skip if request is not an API-request
$request = $event->getRequest();
if (strpos($request->getPathInfo(), '/api') !== 0) {
return;
}
$exception = $event->getException();
$error = [
'type' => $this->getErrorTypeFromException($exception),
// Warning! Passing the exception message without checks is insecure.
// This will potentially leak sensitive information.
// Do not use this in production!
'message' => $exception->getMessage(),
];
$response = new JsonResponse($error, $this->getStatusCodeFromException($exception));
$event->setResponse($response);
}
private function getStatusCodeFromException(Exception $exception): int
{
if ($exception instanceof HttpException) {
return $exception->getStatusCode();
}
return 500;
}
private function getErrorTypeFromException(Exception $exception): string
{
$parts = explode('\\', get_class($exception));
return end($parts);
}
}
Это преобразует любое исключение в JSON-ответ с пользовательским форматом, подобным следующему:
{
"type": "NotFoundException",
"message": "Could not find argument with id x"
}
Этот слушатель будет делать это только для маршрутов, начинающихся с /api
, поэтому, если у вас есть и API, и«Обычный» сайт не должен мешать обработке ошибок по умолчанию.