Relecture RB faite le 17/02/2011

Sommaire :


Généralités

Même dans une application mûre, il n'est de cas pour lesquels une exception ne puisse se produire. esup-commons offre une gestion des exceptions qui évite au développeur de recevoir le message traditionnel de Tomcat :



Ou encore celui de uPortal :
esup-commons permet de remonter les exceptions de manière propre, par exemple :

Cette gestion des exceptions est une véritable aide au développeur, qui peut ainsi connaitre tout le contexte d'exécution au moment où s'est produite l'erreur :


| | |

Configuration

Le gestionnaire d'exception se configure à l'aide du fichier /properties/exceptionHandling/exceptionHandling.xml, dans lequel on déclare le bean exceptionServiceFactory, à partir duquel sont produits les services de gestion des exceptions.

Implémentations disponibles

esup-commons offre plusieurs gestionnaires d'exceptions :

Exemple

On utilisera par exemple :

<bean id="exceptionServiceFactory"
      class="org.esupportail.commons.services.exceptionHandling.CachingEmailExceptionServiceFactoryImpl"
      parent="abstractApplicationAwareBean">
  <property name="smtpService" ref="smtpService" />
  <property name="recipientEmail" value="${exceptionHandling.email}" />
  <property name="exceptionViews" >
    <map>
      <entry key="java.lang.Exception" value="go_exception" />
    </map>
  </property>
  <property name="logLevel" value="${exceptionHandling.logLevel}" />
  <property name="cacheManager" ref="cacheManager" />
</bean>

* La propriété smtpService est le service d'envoi des messages électroniques.

Qui reçoit les rapports d'exception ?

La dernière implémentation (CachingEmailExceptionServiceFactoryImpl) n'envoie les courriers électroniques qu'à l'adresse spécifiée dans la configuration Spring. Lorsque cette classe est étendue dans esup-blank pour, en plus d'une adresse fixée par configuration, envoyer les exceptions à une adresse fixée dans le code (celles des développeurs). Cela permet de remonter automatiquement les exceptions aux développeurs, qui peuvent ainsi suivre à distance les problèmes sur les applications déployées. Même lorsque la classe CachingEmailExceptionServiceFactoryImpl est étendue, les exploitants de l'application disposent de la propriété doNotSendExceptionReportsToDevelopers pour activer ou désactiver cette fonctionnalité.

Vue utilisée pour les rapports d'exceptions

SimpleExceptionServiceFactoryImpl (ainsi que les classes qui en héritent) présente une vue à l'utilisateur avec le contenu de l'erreur. Cette vue peut être configurée en utilisant la propriété exceptionView du bean exceptionServiceFactory. Si cette propriété n'est pas définie, alors la vue /stylesheets/exception.jsp de esup-commons est utilisée par défaut. La vue proposée par défaut présente des détails qui ne sont certainement pas utiles à l'utilisateur. Il convient avant de mettre en production une application de personnaliser la vue /stylesheets/exception.jsp (en la copiant dans le projet de l'application) ou bien d'en créer une autre (par exemple /stylesheets/customizedException.jsp) et d'indiquer au bean exceptionServiceFactory de l'utiliser (à l'aide de la propriété exceptionView).

Il est possible de copier la vue /stylesheets/exception.jsp de esup-commons dans votre projet pour l'adapter et configurer votre gestionnaire d'exception pour pointer vers cette nouvelle vue.

Copier exception.jsp en exception-prod.jsp et simplifier la page pour ne garder que les informations qui vous intéressent. Configurer l'application pour utiliser cette nouvelle vue en cas d'exception.

1. Création de la page exception-prod.jsp dans le répertoire webapp/stylesheets/
2. Modification du fichier exceptionHandling.xml :
Ajout d'une entrée dans la property exceptionViews.

<entry key="java.lang.Exception" value="/stylesheets/exception-prod.jsp" />

3. Créer puis provoquer une exception afin de tester la redirection vers exception-prod.jsp.

Redémarrage de l'application.

La vue /stylesheets/exception.jsp présente à l'utilisateur un bouton permettant de redémarrer l'application. Ce bouton appelle la méthode restart() du contrôleur exceptionController déclaré dans le fichier de configuration /properties/web/controllers.xml.

Exemple de déclaration :

<bean id="exceptionController"
      class="org.esupportail.commons.web.controllers.ExceptionController"
      scope="session">
 </bean>

La méthode restart() de exceptionController appelle la méthode reset() de tous les beans qui implémentent l'interface Resettable.
En conséquence, tout bean (contrôleur, ...) qui doit être réinitialisé lors du redémarrage de l'application doit implémenter l'interface Resettable.

Faire en sorte que, sur une exception, l'attribut value de test2Controller soit vidé.

Implémenter la méthode reset dans le contrôler Test2Controller :

/**
 * @see org.esupportail.formation.web.controllers.AbstractDomainAwareBean#reset()
 */
@Override
public void reset() {
  super.reset();
  value = null;
}


Utilisation de plusieurs vues d'exceptions

Il est possible d'utiliser plusieurs vues d'exceptions en fonction de l'exception levée par l'application :

<property name="exceptionViews" >
  <map>
    <entry
      key="org.esupportail.commons.exceptions.WebFlowException"
      value="/stylesheets/webFlowException.jsp" />
    <entry
      key="org.esupportail.commons.exceptions.ConfigException"
      value="/stylesheets/configException.jsp" />
    <entry
      key="java.lang.Exception"
      value="/stylesheets/exception.jsp" />
  </map>
</property>

Ne pas envoyer de courrier électronique pour certaines exceptions

Il est possible de ne pas envoyer de courrier électronique pour certaines exceptions, en ajoutant la propriété suivante :

<property name="noEmailExceptions" >
  <list>
    <value>
      org.esupportail.commons.exceptions.WebFlowException
    </value>
  </list>
</property>