views:

410

answers:

1

I am playing with the SimpleMappingExceptionResolver to see how it works and to see if it will be of use to us for a client but I am having problems understanding it.

What I have tried is visiting a particular page in my application and having it throw an exception in the handleRequestInternal method.

When I throw a RecoverableDataAccessException (subclass of DataAccessException) then the correct error page is displayed as expected.

When I throw a freemarker.core.InvalidReferenceException or java.lang.NumberFormatException then the exception bubbles through to the page and the default 500 error page (ie, no styling) is shown.

Below is the mapping I am using.

<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="org.springframework.dao.DataAccessException">/general/error/500</prop>
            <prop key="freemarker.core.InvalidReferenceException">/general/error/500</prop>
            <prop key="NumberFormatException">/general/error/500</prop>
        </props>
    </property>
    <property name="defaultErrorView" value="/general/error/500" />
</bean>

I at least expected the default error view to get hold of the exception and display my specific error page but that is not happening.

Am I using the SimpleMappingExceptionHandler correctly here?

[edit] I am using jetty.

[edit] I've realised that the SMER doesn't handle errors thrown during render which explains why it can't catch the ones I've specifically having trouble with. Can the SMER be made to cope with 500 style errors?

+2  A: 

As you've discovered, SimpleMappingExceptionResolver will not work for exceptions thrown in the view layer. It implements the interface HandlerExceptionResolver which, as the name implies, only handles exceptions thrown by the handler (i.e. the controller).

If you need to handle exceptions thrown by the view, you can either write a HandlerInterceptor, overriding the afterCompletion() method, or write a non-Spring servlet Filter. In both cases, you won't get the benefit of Spring's view resolver, you'll have to handle rendering yourself.

One word of warning, though - when you get exceptions in the view layer, it's not always possible to handle them gracefully, since the server may have begun to flush the view output to the client when the exception is thrown, in which case the server cannot then render a separate error page. This is why it's good practice to do as much logic as you can in the controller layer, so that exceptions are caught as early as possible.

skaffman
That's really good advice - thank you
Rachel