web.xml
<error-page> <exception-type>java.lang.Exception</exception-type> <location>/WEB-INF/jsp/uncaughtException.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/jsp/uncaughtException.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/WEB-INF/jsp/notFound.jsp</location> </error-page>
Note how I use the same JSP for 500 errors and Exceptions. From that JSP I log the trace in the server logs (so I can monitor problems occurring in user browsers for example) Below is spring pet clinic uncaughtException.jsp modified to log the complete stacktrace:
<%@ page isErrorPage="true" %> <%@ page import="org.slf4j.Logger" %> <%@ page import="org.slf4j.LoggerFactory" %> <%@ include file="/WEB-INF/jsp/includes.jsp" %> <%@ include file="/WEB-INF/jsp/header.jsp" %> <% final Logger log = LoggerFactory.getLogger("com.nestorurquiza.web.internal-error"); log.error("Internal Server Error", exception); %> Internal error <% try { // The Servlet spec guarantees this attribute will be available //Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception"); if (exception != null) { if (exception instanceof ServletException) { // It's a ServletException: we should extract the root cause ServletException sex = (ServletException) exception; Throwable rootCause = sex.getRootCause(); if (rootCause == null) rootCause = sex; out.println("** Root cause is: "+ rootCause.getMessage()); rootCause.printStackTrace(new java.io.PrintWriter(out)); } else { // It's not a ServletException, so we'll just show it exception.printStackTrace(new java.io.PrintWriter(out)); } } else { out.println("No error information available"); } // Display cookies out.println("\nCookies:\n"); Cookie[] cookies = request.getCookies(); if (cookies != null) { for (int i = 0; i < cookies.length; i++) { out.println(cookies[i].getName() + "=[" + cookies[i].getValue() + "]"); } } } catch (Exception ex) { ex.printStackTrace(new java.io.PrintWriter(out)); } %>
<%@ include file="/WEB-INF/jsp/footer.jsp" %>
applicationContext.xml
<bean class="com.nestorurquiza.web.handler.CustomSimpleMappingExceptionResolver" > <property name="exceptionMappings"> <props> <prop key="org.springframework.web.servlet.PageNotFound">notFound</prop> <prop key="java.lang.Exception">failure</prop> </props> </property> </bean>
Note I use a custom MappingExceptionResolver. I do this again to make sure I log the error. I strongly believe error monitoring must be done from outside the application.
Below is the code for CustomSimpleMappingExceptionResolver:
package com.nestorurquiza.web.handler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; public class CustomSimpleMappingExceptionResolver extends SimpleMappingExceptionResolver{ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { final Logger log = LoggerFactory.getLogger(CustomSimpleMappingExceptionResolver.class); log.error(null,ex); return super.resolveException(request, response, handler, ex); } }
No comments:
Post a Comment