0

I am using the following generic class to handle all types of exceptions in my app. It handles most of the exceptions but fails to for some such as "org.apache.tiles.impl.CannotRenderException". How can I make it catch all types of exceptions?

Some of the technologies that I am using are: Spring 4.0.0.RELEASE, Tiles 2.2, Maven 1.6, Spring Webflow 2.4.0.RELEAS

@ControllerAdvice
class GenericDefaultExceptionHandler {
    public static final String DEFAULT_ERROR_VIEW = "error/error";
    private static final String DEFAULT_ERROR_SUBJECT = "Exception occurred";
    final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private MailService mailService;

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
            throw e;
        ModelAndView mav = new ModelAndView();
        mav.addObject("exception", e);
        mav.addObject("url", req.getRequestURL());
        mav.setViewName(DEFAULT_ERROR_VIEW);
        //send email to system admin
        sendMessageToAdmin(e.toString(),req.getRequestURL().toString());
        logger.error(e.toString());
        return mav;
    }

    private void sendMessageToAdmin(String exceptionAsMessage, String url) {
        try {
            StringBuilder errorMessage = new StringBuilder();
            errorMessage.append("Exception on request URL :");
            errorMessage.append(url);
            errorMessage.append("\n\n");
            errorMessage.append("The Exception was: ");
            errorMessage.append(exceptionAsMessage);
            mailService.sendMailWithSubject(DEFAULT_ERROR_SUBJECT,errorMessage.toString());
        } catch (Exception e) {

        }
    }
}

Thanks

2 Answers 2

2

The problem is that your handler catches the exception in your controller, but tiles exception are thrown in the view after the controller has finished its job. You can try to handle them using a filter :

public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    ...
    try {
        chain.doFilter(request, response);
    }
    catch (Exception ex) {
        // your stuff
        ...
        throw new ServletException(ex);
    }
}

Independantly of that (or in addition), you can also ask the container to use some views when it find exceptions or when the controllers uses sendError with some configuration in the web.xml file :

<!-- error-code related error pages -->
<error-page>
    <error-code>404</error-code>
    <location>/ErrorHandler</location>
</error-page>
<error-page>
    <error-code>403</error-code>
    <location>/ErrorHandler</location>
</error-page>

<!-- exception-type related error pages -->
<error-page>
    <exception-type>
          javax.servlet.ServletException
    </exception-type >
    <location>/ErrorHandler</location>
</error-page>

<error-page>
    <exception-type>java.io.IOException</exception-type >
    <location>/ErrorHandler</location>
</error-page>
Sign up to request clarification or add additional context in comments.

1 Comment

Filter is the way to go for sure. Our exception filter emails us all the exceptions that occur in our site and adds interesting metadata to the email: session id, remote address, user agent, etc... But we also black listed some exceptions, like socket exception, that occur several 1000 times per day and are fairly meaningless.
0

Yes, the Filter worked for me. I created an exception class that extends GenericFilterBean of Spring filter and registered it inside my ApplicationConfig.

public class ApplicationConfig implements WebApplicationInitializer {
    .....
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        .....
        FilterRegistration.Dynamic exception = servletContext.addFilter("genericExceptionFilter", new GenericExceptionFilter());
        exception.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
        .....
    }
}

Thank you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.