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