Bonjour à tous,
Petite bafouille ce soir, une plus longue viendra, il me faut le temps de l'écrire. Aujourd'hui le sujet est une question qu'on m'a posée il n'y a pas longtemps lors de l'une des mes formations
symfony : est il possible d'envoyer un mail lorsqu'une erreur 500 se produit sur le site de production ?
La réponse est non mais oui ... en partie. Je m'explique : il est possible d'attraper les exceptions crées dans symfony et d'envoyer un mail. Mais en aucun cas les erreurs PHP ne peuvent être
attrapées ... on ne peut rien faire dans ce cas.
Comment attraper les exceptions dans symfony ?
Très facile, le framework symfony 1.0 est composé de couches appelées
filtres. Lors de l'exécution, chacune des requêtes passe au travers des filtres et une fois la réponse calculée,
repasse dans l'autre sens. Pour plus de précisions sur ce système de filtres, je vous propose la lecture du
livre à
ce sujet.
Il est évidemment possible d'ajouter un filtre dans la pile, comme par exemple un filtre qui attraperait les erreurs des filtres «
en dessous» c'est à dire là ou vous auriez placé le
code de vos actions et templates, utilisé votre modèle et vos bibliothèques.
Le code du filtre est très simple, il suffit de faire un try catch sur l'exécution de la pile de filtres du «
dessous». En cas d'exception, envoyer un mail et propager l'exception
pour que symfony s'en occupe. Dans le répertoire lib de votre application, placer un fichier catchErrorFilter.class.php qui contient le code suivant (mis à jour suite à la pertinente remarque
de
Niko dans les commentaires ):
<?php
class catchErrorFilter extends sfFilter
{
public function execute ($filterChain)
{
// Execute next filter in the chain
try
{
$filterChain->execute();
}
// Si l'exception est due a un redirect
// ne pas envoyer de notification
catch (sfStopException $e)
{
throw $e; # propager l'exception
}
// Toute autre exception est reportee
catch (Exception $e)
{
// envoyer un mail ici
throw $e; # propager l'exception
}
}
}
Reste à
configurer symfony pour enregistrer votre nouveau filtre et le placer dans la pile des filtres. Le fichier filters.yml dans le répertoire de configuration de votre application est
fait pour cela, il devrait ressembler à cela :
rendering: ~
security: ~
# insert your own filters here
catch_error:
class: catchErrorFilter
param:
condition: %APP_CATCH_ERRORS%
cache: ~
common: ~
execution: ~
On enregistre le filtre et on demande à symfony de ne l'exécuter qu'à condition de que la variable de configuration «
APP_CATCH_ERROR» soit vraie.
Cela va nous permettre de n'utiliser ce filtre qu'en environnement de production et éviter ainsi de recevoir des mails lors des erreurs (plus fréquentes) sur les environnements de développement. Il
convient dons de placer cette directive dans le fichier de conf app.yml :
all:
catch_errors: off
prod:
catch_errors: on
Voila, le tour est joué ...