I am using Symfony and i have created custom ExceptionListener to handle error.
class ExceptionListener
{
protected $templating;
protected $kernel;
public function __construct(EngineInterface $templating, $kernel)
{
$this->templating = $templating;
$this->kernel = $kernel;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
// exception object
$exception = $event->getException();
// new Response object
$response = new Response();
$response->setContent(
// create you custom template AcmeFooBundle:Exception:exception.html.twig
$this->templating->render(
'Exception/exception.html.twig',
array('exception' => $exception)
)
);
// HttpExceptionInterface is a special type of exception
// that holds status code and header details
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$this->container->get('monolog.logger.db')->info('something happened 34', [
'foo' => 'bar'
]);
$response->setStatusCode(500);
}
if($exception instanceof FatalThrowableError){
return $this->templating->render(
'Exception/exception.html.twig'
);
}
// set the new $response object to the $event
$event->setResponse($response);
}
}
and in service
kernel.listener.acme_foo_exception_listener:
class: AppBundle\Listener\ExceptionListener
arguments: [@templating, @kernel]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
My aim is to when symfony throws exception i need to log error in database so i have created Logger event as per below link and it works fine when i called in controller but this event doesn't work when i called inside ExceptionListener.
I got following error
Notice: Undefined property: AppBundle\Listener\ExceptionListener::$container in
can any one help me how i can pass container inside Listener
As said by geoforce your service doesn't know about the container. Quick fix for this by changing the service arguments:
arguments: [@templating, @container]
While changing the listener constructor to:
public function __construct(EngineInterface $templating, ContainerInterface $container)
{
$this->container = $container;
// ...
This should work, but injecting the entire container is quite an overkill and should definitely be done differently. Inject just what you need:
arguments: [@templating, '@monolog.logger.db']
And your constructor:
public function __construct(EngineInterface $templating,
LoggerInterface $logger)
{
$this->logger = $logger;
// ...
Log with $this->logger->info(...)
.
Since you've said that you're new to Symfony, I'd heavily recommend reading the DI component (http://symfony.com/doc/current/components/dependency_injection.html) docs. Understanding what DI does and how it works is mandatory to work with MVC frameworks like Symfony.