Сегодня я хочу поделиться своим скромным опытом и показать, как можно сделать перехватчик исключений, не используя Event Listener. Но сначала пару слов о том, зачем это нужно.
Я считаю, что использование Event Listener'ов в обычном приложении делает код запутанным, к тому же многие неопытные разработчики злоупотребляют данным подходом (сам так делал). А вот использование сервисов делает код понятным, так как они вызываются в том месте, в котором объявлены. И как вы уже поняли, далее речь пойдет именно о сервисах.
Итак, начнем.
Сначала переопределим ExceptionController, о чем скромно намекает официальная документация:
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