symfony - Symfony2 kernel exception event not handling fatal error exception in production mode -
i make listener exception handling. below code
services.yml
kernel.listener.prod_exception_listener: class: mybundle\listener\exceptionlistener tags: - { name: kernel.event_listener, event: kernel.exception, method: onkernelexception }
exceptionlistener.php
<?php namespace mybundle\listener; use symfony\component\httpkernel\event\getresponseforexceptionevent; use symfony\component\httpfoundation\response; use symfony\component\httpkernel\exception\httpexceptioninterface; class exceptionlistener { public function onkernelexception(getresponseforexceptionevent $event) { // no fatal exception goes here others coming in function // 403,404,500 coming in block } }
what additional work need fatal exceptions in production mode? because in dev mode fatal errors coming in listener.
i solved following way, in services.yml
api_exception_subscriber: class: appbundle\eventlistener\apiexceptionsubscriber arguments: ['%kernel.debug%', '@api.response_factory', '@logger'] tags: - { name: kernel.event_subscriber } api.response_factory: class: appbundle\api\responsefactory
my response factory like:
<?php namespace appbundle\api; use symfony\component\httpfoundation\jsonresponse; class responsefactory { public function createresponse(apiproblem $apiproblem) { $data = $apiproblem->toarray(); $response = new jsonresponse( $data, $apiproblem->getstatuscode() ); $response->headers->set('content-type', 'application/json'); return $response; } }
and api subscriper class
<?php namespace appbundle\eventlistener; use appbundle\api\apiproblem; use appbundle\api\apiproblemexception; use appbundle\api\responsefactory; use psr\log\loggerinterface; use symfony\component\eventdispatcher\eventsubscriberinterface; use symfony\component\httpkernel\event\getresponseforexceptionevent; use symfony\component\httpkernel\kernelevents; use symfony\component\httpfoundation\jsonresponse; use symfony\component\httpkernel\exception\httpexceptioninterface; class apiexceptionsubscriber implements eventsubscriberinterface { private $debug; private $responsefactory; private $logger; public function __construct($debug, responsefactory $responsefactory, loggerinterface $logger) { $this->debug = $debug; $this->responsefactory = $responsefactory; $this->logger = $logger; } public function onkernelexception(getresponseforexceptionevent $event) { // reply /api urls if (strpos($event->getrequest()->getpathinfo(), '/api') !== 0) { return; } $e = $event->getexception(); $statuscode = $e instanceof httpexceptioninterface ? $e->getstatuscode() : 500; // allow 500 errors thrown if ($this->debug && $statuscode >= 500) { return; } $this->logexception($e); if ($e instanceof apiproblemexception) { $apiproblem = $e->getapiproblem(); } else { $apiproblem = new apiproblem( $statuscode ); /* * if it's httpexception message (e.g. 404, 403), * we'll rule exception message safe * client. otherwise, sensitive * low-level exception, should *not* exposed */ if ($e instanceof httpexceptioninterface) { $apiproblem->set('detail', $e->getmessage()); } } $response = $this->responsefactory->createresponse($apiproblem); $event->setresponse($response); } public static function getsubscribedevents() { return array( kernelevents::exception => 'onkernelexception' ); } /** * adapted core symfony exception handling in exceptionlistener * * @param \exception $exception */ private function logexception(\exception $exception) { $message = sprintf('uncaught php exception %s: "%s" @ %s line %s', get_class($exception), $exception->getmessage(), $exception->getfile(), $exception->getline()); $iscritical = !$exception instanceof httpexceptioninterface || $exception->getstatuscode() >= 500; $context = array('exception' => $exception); if ($iscritical) { $this->logger->critical($message, $context); } else { $this->logger->error($message, $context); } } }
Comments
Post a Comment