Gestion et journalisation d'erreur

Si vous tentez de naviguez à l'URL http://hostname/blog/index.php?page=EditPost&id=100, vous verrez la page d'erreur suivante parce que le message avec l'ID 100 n'existe pas pour le moment. Nous voudrions personnaliser cette page d'erreur de manière à ce qu'elle garde la présentation générale du site. Nous voudrions aussi journaliser cette erreur pour étudier le comportement des utilisateurs. Dans cette section, nous allons mettre en place ces deux fonctionnalités.

Une des tâches importantes dans les applications Web est la gestion des erreurs ainsi que leurs journalisation. Il y a deux types d'erreurs qui peuvent se produire dans une application PRADO : celles provenant des développeurs et celles des utilisateurs. Les premières doivent être résolues avant que l'application ne soit en production, tandis que les deuxièmes sont généralement un problème de prise en charge au niveau du design et doivent être gérées proprement (ie: journaliser cette erreur et indiquer à l'utilisateur que faire après). PRADO fournit un ensemble de fonctionnalités très utiles pour gérer et journaliser les erreurs.

Personnalisation de la gestion d'erreur

PRADO charge de manière implicite un module de gestion d'erreurs. Nous voulons personnaliser ce module pour qu'il affiche une page spécifique pour les erreurs causées par les utilisateurs. Nous modifions donc notre application comme ci-dessous :

...... ...... ...... ......

La classe BlogErrorHandler comme spécifiée ci-dessus est un nouveau gestionnaire d'erreur que nous allons créer après. Il étend et remplace le module par défaut TErrorHandler.

Nous créons un fichier nommé protected/BlogErrorHandler.php avec le contenu suivant. La classe BlogErrorHandler surcharge deux méthodes de TErrorHandler :

Prado::using('System.Exceptions.TErrorHandler'); Prado::using('Application.BlogException'); class BlogErrorHandler extends TErrorHandler { /** * Renvoi le fichier gabarit utilisé pour afficher l'erreur. * Cette méthode surcharge la méthode originale. */ protected function getErrorTemplate($statusCode,$exception) { // on utilise notre propre gabarit pour BlogException if($exception instanceof BlogException) { // récupère le chemin du fichier de gabarit : protected/error.html $templateFile=Prado::getPathOfNamespace('Application.error','.html'); return file_get_contents($templateFile); } else // sinon on utilise le gabarit par défaut. return parent::getErrorTemplate($statusCode,$exception); } /** * Gère les erreurs causées par les utilisateurs. * Cette méthode surcharge la méthode originale. * Elle est appelée lorsqu'une exception utilisateur est générée. */ protected function handleExternalError($statusCode,$exception) { // Journaliser l'erreur (seulement pour BlogException) if($exception instanceof BlogException) Prado::log($exception->getErrorMessage(),TLogger::ERROR,'BlogApplication'); // appelle l'implémentation de la classe parente parent::handleExternalError($statusCode,$exception); } }

Dans le code précédent, nous spécifions que lorsqu'une exception de type BlogException est générée, nous utilisons le gabarit protected/error.html pour afficher l'erreur. Par ailleurs, nous devons créer la classe BlogException et remplacer toutes les occurrences de THttpException dans notre code (par exemple dans les pages EditUser et ReadPost). Nous devons aussi créer le gabarit protected/error.html. La classe BlogException hérite de THttpException et est vide. Le fichier de classe est enregistré sous protected/BlogException.php.

class BlogException extends THttpException { }

Ci-dessous le contenu du gabarit protected/error.html. Remarquez que ce gabarit n'est pas un gabarit PRADO, ceci parce qu'il ne reconnait qu'un nombre limité de mots clés, par exemple %%ErrorMessage%%, %%ServerAdmin%%.

%%ErrorMessage%%

%%ErrorMessage%%

Une erreur est apparue lors du traitement de votre demande.

Si vous pensez que c'est une erreur de notre serveur, veuillez contacter webmaster.

Journalisation des erreurs

Dans la méthode handleExternalError() de BlogErrorHandler, nous appelons Prado::log() pour journaliser l'erreur si elle est de type BlogException. L'erreur est stockée en mémoire. Pour enregistrer le journal d'erreur sur un support non volatil, tel que le disque dur ou une base de données, nous devons indiquer à PRADO comment procéder. Ceci est fait par la configuration d'application suivante :

...... ...... ...... ......

Dans le code ci-dessus, nous ajoutons une "route" pour enregistrer le journal d'erreur dans un fichier. Nous spécifions aussi le filtre de catégorie BlogApplication, de manière à ce que seules les erreurs de type BlogApplication soient sauvegardées. Cette possibilité permet de réduire la taille du journal et d'en améliorer la lisibilité.

Test

Pour voir comme notre blog se comporte suite à une demande invalide, nous naviguons à l'URL http://hostname/blog/index.php?page=posts.ReadPost&id=100. Nous devrions voir la page suivante qui est différente de celle vue précédemment.

Si nous regardons dans le dossier protected/runtime, nous devrions y trouver un fichier nommé prado.log. C'est le journal d'erreur que nous venons juste de paramétrer. Le fichier pourrait contenir quelque chose comme :

Jun 28 22:15:27 [Error] [BlogApplication] Unable to find the specified post. Jun 29 08:42:57 [Error] [BlogApplication] Unable to find the specified post.