Search code examples
springexceptionportlet

Spring Exception Handling - how to use ExceptionResolver and @ExceptionHandler at the same time


I developed a web application where form validation exceptions are supposed to be handled by @ExceptionHandler (needs to be flexible) and general system exceptions by SimpleMappingExceptionResolver (doing stuff like email notification etc.).

Problem is, that if I use both, exceptions that are mapped for @ExceptionHandler don't get to the @ExceptionHandler but are grabbed by ExceptionResolver as defaultError.

Any idea what to do to make it work together ?

@ExceptionHandler(ValidatorException.class)
public String handleFormException(ValidatorException ex, ActionRequest actionRequest) {
    logger.error(ex.getMessage());
    //TODO make conditions
    return "mainOrderForm";
}

@ActionMapping(params = "action=addDocOrder")
public void addDocOrder(@ModelAttribute("order") CstOrderBeanImpl orderBean,
        BindingResult result, ActionRequest actionRequest, ActionResponse response) 
        throws PortalException, SystemException, ValidatorException {
    logger.info("Adding Form Order");
    Calendar cal = TimeUtils.getEuDeadLine(orderBean);
    orderBean.setDeadLine(cal.getTime());
    ValidatorException ve = validateService.validate(orderBean, result, actionRequest, validator);
    if (ve != null) throw ve;
(...)

In DispatcherPortlet, there is

catch (Exception ex) {
    // Trigger after-completion for thrown exception.
    triggerAfterActionCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
(...)

Which checks for interceptors, but none exists, so it does the default...

I just point out, that it's Portlet environment, there is usually less "views"...driven by parameters..


Solution

  • Maybe as a workaround in ExceptionResolver you could dynamically invoke a handler method of your choice.

    public ModelAndView resolveException(RenderRequest req, RenderResponse res, Object handler,Exception exc) {
        if(exc instanceof ValidatorException) {
            try {
                java.lang.reflect.Method m = handler.getClass().getMethod("someMethod", (Class<?>)null /* method parameters? */);
                m.invoke(handler,new Object[]{(ValidatorException)exc,req/*, res - maybe?*/});
            } catch(Exception e) {
                // Handle exception
            }
        }
    
        // Send email of the error etc..
    }
    

    It's not exactly an elegant solution, but should work..