Détecter les exceptions lors des appels à DWR

Suite à l’article sur la détection des exceptions grâce à l’utilisation du Framework Spring, il est apparut qu’il n’était pas possible d’utiliser le même procédé pour les exceptions lancés depuis un appel Ajax avec le framework DWR. Une des solutions pour pouvoir détecter les exceptions lors de l’appel à vos méthodes DWR est d’utiliser la programmation par aspect proposé par Spring.

Pour notre exemple, on suppose que les classes Dwr à surveiller se trouve dans le même package java.

Dans le fichier de configuration:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

	<!-- Un bean avec des méthodes DWR -->
	<bean id="maClasseDwr" class="demo.web.dwr.action.impl.MaClasseDwrImpl">
	</bean>

       <!-- Le bean qui va se charger de catcher les exceptions -->
	<bean id="handlerExceptionDwr" class="demo.web.interceptor.HandlerExceptionDwr">
	</bean>

	<aop:config>
	  <aop:pointcut id="servicePointcutDwr"  expression="execution(* demo.web.dwr.action.*.*(..))"/>
	  <aop:aspect id="loggingAspectDwr" ref="handlerExceptionDwr">
	    <aop:around method="handlingException" pointcut-ref="servicePointcutDwr"/>
	  </aop:aspect>
	</aop:config>
</beans>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;

public class HandlerExceptionDwr {

	private final Log logger = LogFactory.getLog(getClass());

	/**
	 * Fonction permettant de catcher les exceptions des appels DWR.
	 *
	 * @param pjp
	 *            pjp
	 * @return Object
	 * @throws Throwable
	 *             Throwable
	 */
	public Object handlingException(ProceedingJoinPoint pjp) throws Throwable {

		try {
            //très important, on appelle la méthode
            // que l'on souhaitait exécuter au départ
             Object o = pjp.proceed();
             return o; //On retourne l'objet retourné par la méthode
		} catch (Exception exception) {
            // On laisse passer l'erreur mais on envoie l'exception par mail
            String name = pjp.getSignature().getName(); //Nom de la méthode

            //Traitement à effectuer sur l'exception
             //Dans certain projet, j'informe les administrateurs par mail

            //On trace l'erreur
            logger.error("Exception lors de l'appel à la méthode : " + name, exception);

            //Nous laissons passer l'exception et la renvoyons
             throw exception;
		}
	}
}

Dans cet exemple, l’exception catché est retourné à l’utilisateur final. Dans le cas de Dwr, c’est le navigateur du client (ou plus directement le script javascript) qui va recevoir l’exception.

Le plus souvent, l’utilisateur final n’a pas besoin d’avoir les informations techniques sur une erreur. Cette solution peut être utile pour intercepter les exceptions techniques et retourner une exception plus light et plus compréhensible par l’utilisateur. Mais vous êtes libre d’adapté cette solution en fonction de vos besoins.