Handle database connection exception via custom handler I want to catch the database connection exceptions with a custom handler. I have already built an handler which is overriding the default logger factory, but now I want to use that custom handler to log database exceptions, without hacking the core.

I can see the connection driver uses the following code in open(). 

try {
  $pdo = new \PDO($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
}
catch (\PDOException $e) {
  if ($e-&gt;getCode() == static::DATABASE_NOT_FOUND) {
    throw new DatabaseNotFoundException($e-&gt;getMessage(), $e-&gt;getCode(), $e);
  }
  if ($e-&gt;getCode() == static::ACCESS_DENIED) {
    throw new DatabaseAccessDeniedException($e-&gt;getMessage(), $e-&gt;getCode(), $e);
  }
  throw $e;
}


I am not sure how I can catch the exception and log it using the handler. How can I achieve this?
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-&gt;logger = $logger;
  }

  public function onException(GetResponseForExceptionEvent $event) {
    $exception = $event-&gt;getException();
    if ($exception instanceof DatabaseAccessDeniedException) {
      $this-&gt;logger-&gt;get('php')-&gt;error('Custom logging message');
      $response = new Response('Custom error message', 500);
      $event-&gt;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?