Как написать свой ExceptionHandler?

Чтобы написать собственный обработчик исключений (ExceptionHandler) в Symfony, вам необходимо следовать нескольким шагам.

Шаг 1: Создание класса исключения
Сначала создайте класс исключения, который будет представлять ваше исключение. Этот класс должен наследоваться от базового класса исключения - "Exception".

namespace AppException;

class CustomException extends Exception
{
    public function __construct($message, $code = 0, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
}

Шаг 2: Создание обработчика исключений
Следующий шаг - создать собственный обработчик исключений. Этот класс должен реализовывать интерфейс "ExceptionHandlerInterface" и определить метод "handle". Внутри этого метода вы можете определить необходимую логику для обработки исключений и генерации ответа.

namespace AppException;

use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentHttpKernelEventExceptionEvent;
use SymfonyComponentHttpKernelExceptionHttpExceptionInterface;
use SymfonyComponentHttpKernelExceptionNotFoundHttpException;
use SymfonyComponentHttpKernelExceptionAccessDeniedHttpException;
use SymfonyComponentHttpKernelExceptionUnauthorizedHttpException;
use SymfonyComponentHttpKernelExceptionMethodNotAllowedHttpException;

class ExceptionHandler implements SymfonyComponentHttpKernelEventListenerExceptionListenerInterface
{
    public function handle(ExceptionEvent $event)
    {
        $exception = $event->getThrowable();
        
        // Кастомная обработка исключений
        if ($exception instanceof CustomException) {
            $response = new Response('Custom Exception', Response::HTTP_BAD_REQUEST);
            $event->setResponse($response);
        } elseif ($exception instanceof NotFoundHttpException) {
            $response = new Response('Not Found', Response::HTTP_NOT_FOUND);
            $event->setResponse($response);
        } elseif ($exception instanceof AccessDeniedHttpException) {
            $response = new Response('Access Denied', Response::HTTP_FORBIDDEN);
            $event->setResponse($response);
        } elseif ($exception instanceof UnauthorizedHttpException) {
            $response = new Response('Unauthorized', Response::HTTP_UNAUTHORIZED);
            $event->setResponse($response);
        } elseif ($exception instanceof MethodNotAllowedHttpException) {
            $response = new Response('Method Not Allowed', Response::HTTP_METHOD_NOT_ALLOWED);
            $event->setResponse($response);
        }
    }
}

Шаг 3: Зарегистрировать обработчик исключений
Чтобы обработчик исключений корректно работал, вам необходимо зарегистрировать его в вашем файле конфигурации "services.yaml" или "services.yml".

services:
    AppExceptionExceptionHandler:
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

Теперь ваш собственный обработчик исключений готов к использованию. При возникновении исключений, вы можете определить необходимую логику обработки исключений, и генерации ответа в методе "handle" вашего обработчика.