Le framework Symfony2 permet de s’abonner à des événements en créant des listener, dans notre cas ce sera l’événement kernel.exception
.
Une fois l’exception capturée, on pourra l’enregistrer dans des fichiers de logs, l’envoyer par mail etc.
Voici une manière de réaliser un envoi de mail automatique lorsque une exception est levée.
On commence par créer le service dans le fichier app/config/services.yml
services:
app.exception_listener:
class: AppBundleEventListenerExceptionListener
calls:
- [setMailer, ["@mailer"]]
- [setTemplating, ["@templating"]]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
On renseigne la classe qui va gérer l’abonnement à l’événement, et qu’il va falloir créer (ExceptionListener), puis on initialise deux fonctions : setMailer
et setTemplating
avec en argument les services nativement existants mailer
et templating
.
Cela nous permettra de les utiliser à l’intérieur de notre classe.
namespace AppBundle\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Bundle\TwigBundle\TwigEngine;
class ExceptionListener implements EventSubscriberInterface
{
private $mailer;
private $templating;
private $dontCare = array(
'Symfony\Component\HttpKernel\Exception\NotFoundHttpException',
'Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException',
);
/**
* @param GetResponseForExceptionEvent $event
* @return void
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
// pas de mail d'erreur pour certaines exceptions
if (in_array(get_class($event->getException()), $this->dontCare)) {
return;
}
// contenu du mail
$body = $this->templating->render('mails/error.html.twig', array(
'exception' => $event->getException(),
));
$message = Swift_Message::newInstance()
->setFrom('user@domain.com', 'John Doe')
->setTo('user@domain.com')
->setSubject('[Mon appli] Erreur !')
->setBody($body, 'text/html');
$this->mailer->send($message);
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return array(
'kernel.exception' => 'onKernelException'
);
}
/**
* @param Swift_Mailer $mailer
* @return void
*/
public function setMailer(\Swift_Mailer $mailer)
{
$this->mailer = $mailer;
}
/**
* @param TwigEngine $templating
* @return void
*/
public function setTemplating(TwigEngine $templating)
{
$this->templating = $templating;
}
}
Le code est assez compréhensible, le fonction onKernelException
n’enverra pas de mail si c’est une erreur de type « NotFoundHttpException » ou « AccessDeniedHttpException ».
Le contenu du mail est géré dans le template app/Resources/views/mails/error.html.twig
, voici un extrait :
<h3>Exception information :</h3>
<p>
<b>Message : </b>{{ exception.getMessage() }} (code {{ exception.getCode() }})
</p>
<ul>
<li><strong>Fichier : </strong>{{ exception.getFile() }}</li>
<li><strong>Ligne : </strong>{{ exception.getLine() }}</li>
…