- PVSM.RU - https://www.pvsm.ru -

Symfony2 перехватчик исключений с помощью сервисов или как избежать использования Event Listener

Сегодня я хочу поделиться своим скромным опытом и показать, как можно сделать перехватчик исключений, не используя Event Listener. Но сначала пару слов о том, зачем это нужно.

Я считаю, что использование Event Listener'ов в обычном приложении делает код запутанным, к тому же многие неопытные разработчики злоупотребляют данным подходом (сам так делал). А вот использование сервисов делает код понятным, так как они вызываются в том месте, в котором объявлены. И как вы уже поняли, далее речь пойдет именно о сервисах.

Итак, начнем.

Сначала переопределим ExceptionController, о чем скромно намекает официальная документация [1]:

namespace AppBundleController;

use SymfonyBundleTwigBundleControllerExceptionController as Controller;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpKernelExceptionFlattenException;
use SymfonyComponentHttpKernelLogDebugLoggerInterface;
use AppBundleExceptionExceptionHandler;

class ExceptionController extends Controller
{
    public function __construct(ExceptionHandler $handler) 
    {
        $this->handler = $handler;
    }

    public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null)
    {
        $message = $this->handler->handle($exception)->getMessage();

        return new JsonResponse(array(
            'message' => $message
        ));
    }

}

Далее создадим сервис, который занимается обработкой исключений:

namespace AppBundleException;

use SymfonyComponentSecurityCoreExceptionAccessDeniedException;

class ExceptionHandler
{
    private $message = null;

    public function handle($exception)
    {
        switch($exception->getClass()) {
            case 'SymfonyComponentSecurityCoreExceptionInsufficientAuthenticationException' :
                $this->message = "Need full authentication";
                break;
            case 'SymfonyComponentSecurityCoreExceptionAccessDeniedException':
                $this->message = "Access Denied";
                break;
            /**
            * Указываем действия для всех нужных исключений
            **/
            default:
                break;
        }

        return $this;
    }

    public function getMessage()
    {
        return $this->message;
    }
}

Теперь регистрируем наш сервис:

# services.yml
app_bundle.exception.handler:
    class: AppBundleExceptionExceptionHandler

Далее регистрируем наш контроллер как сервис(не забываем передать в него Exception Handler):

# services.yml
app_bundle.exception.controller:
    class: AppBundleControllerExceptionController
    arguments:
        - @app_bundle.exception.handler

Осталось самое главное: указать в config.yml, что исключения обрабатывает именно наш контроллер:

# config.yml
# Twig Configuration
twig:
    exception_controller: app_bundle.exception.controller:showAction

Надеюсь на вашу конструктивную критику, а также на то, что для кого-то эта статья окажется полезной.

Автор: ivanuzzo

Источник [2]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/symfony/110735

Ссылки в тексте:

[1] официальная документация: http://symfony.com/doc/current/cookbook/controller/error_pages.html#overriding-the-default-exceptioncontroller

[2] Источник: https://habrahabr.ru/post/276155/