Envoyer les exceptions par mail avec Symfony2

Logo SymfonyLe 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>
   …
Share Button

Laisser un commentaire.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.