To instead show a more appropriate 503 service unavailable message, you need to create custom exception listener. While the custom exception listener will listen to all exceptions, you can specify exception type checks inside it.
In your services.yml you need to specify the listener:
> src\Acme\AppBundle\Resources\config\services.yml
services:
kernel.listener.your_pdo_listener:
class: Acme\AppBundle\EventListener\YourExceptionListener
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
Now you need to create the listener class:
> src\Acme\AppBundle\EventListener\AcmeAppBundleListener.php
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use PropelException;
// use DoctrineException;
class YourExceptionListener implements EventSubscriberInterface
{
$env = $this->container->getParameter('kernel.environment');
if ($env == 'dev' || $env == 'test') {
// show default exception
return;
}
$exception = $event->getException();
// only customize propel or doctrine ie database exceptions
// if (!$exception instanceof DoctrineException) {
if (!$exception instanceof PropelException) {
// show default exception
return;
}
$path = $event->getRequest()->getPathInfo();
$response = new Response();
// set status text
$exception_msg = $exception->getMessage();
if (stripos($exception_msg, 'Unable to open PDO connection') !== false) {
$response->setStatusCode(Response::HTTP_SERVICE_UNAVAILABLE);
$status_text = $this->container->getParameter("message.error.unable_to_connect");
} else {
// show default exception
return;
}
// add exception code, if set
$exception_code = $exception->getCode();
if ($exception_code > 0) {
$status_text .= " [".$exception_code."]";
}
$response->setContent(
$this->templating->render(
'AcmeAppBundle:Exception:exception.html.twig',
[
'status_code' => $response->getStatusCode(),
'status_text' => $status_text
]
)
);
$event->setResponse($response);
}
Add the message configuration:
> src\Acme\AppBundle\Resources\config\messages.yml
parameters:
message.error.unable_to_connect: "Unable to connect to service at the moment"
Create the exception template:
> src\Acme\AppBundle\Resources\views\Exception\exception.html.twig
<!DOCTYPE html>
<html><head>
<meta charset="{{ _charset }}" />
<title>An Error Occurred: {{ status_text }}</title>
</head>
<body>
<h1>Zork! An Error Occurred</h1>
<h2>The server returned a "{{ status_code }} {{ status_text }}".</h2>
<div>This should be temporary, but if not, please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.</div>
</body>
</html>
Stop your database or in your code throw DoctrineException or PropelException and you should see the new exception page.
Reference
https://stackoverflow.com/questions/29732630/catching-database-exceptions-in-symfony2
End of document. Thanks for reading.