To handle the logging for a specific exception implement an exception subscriber with a priority higher than 50, so that it runs before Drupal\Core\EventSubscriber\ExceptionLoggingSubscriber
:
src/EventSubscriber/ExampleExceptionSubscriber
namespace Drupal\mymodule\EventSubscriber;
use Drupal\Core\Database\DatabaseAccessDeniedException;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Example for catching a DatabaseAccessDeniedException
*/
class ExampleExceptionSubscriber implements EventSubscriberInterface {
/**
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected $logger;
public function __construct(LoggerChannelFactoryInterface $logger) {
$this->logger = $logger;
}
public function onException(GetResponseForExceptionEvent $event) {
$exception = $event->getException();
if ($exception instanceof DatabaseAccessDeniedException) {
$this->logger->get('php')->error('Custom logging message');
$response = new Response('Custom error message', 500);
$event->setResponse($response);
}
}
public static function getSubscribedEvents() {
$events[KernelEvents::EXCEPTION][] = ['onException', 60];
return $events;
}
}
mymodule.services.yml
services:
mymodule.exception.subscriber:
class: Drupal\mymodule\EventSubscriber\ExampleExceptionSubscriber
arguments: ['@logger.factory']
tags:
- { name: event_subscriber }
If you don't set a response this subscriber only logs the error and the response is set by a subscriber with a lower priority. In this case you get two log entries, one from your subscriber and one from ExceptionLoggingSubscriber
, because the dispatcher runs the event subscribers until one returns a response. Logging does not stop this.
Another option would be to extend ExceptionLoggingSubscriber, put the custom code in ExceptionLoggingSubscriber::onException and call the parent method to run standard logging when your custom code doesn't apply. Instead of putting the service in mymodule.services.yml you need to swap the existing service in the container then, see https://www.drupal.org/docs/8/api/services-and-dependency-injection/altering-existing-services-providing-dynamic-services
You find more infos about exception handling here How do handle exceptions?