Hi,

I've been strugling for a while with exception handling. I've been trying to ensure:
1) all exceptions are displayed consistently regardless of where / how the exception is raised.
2) the root cause exception is always displayed,


I'm not saying this is the best solution, nor even a 'correct' solution, but it is a way I have found that works with the least amount of coding - so I thought it'd be useful to share.

I have tested the following situations where exceptions are raised
1) Action
2) JSP
3) JSP compile error
4) a jsp included by tiles / jsp:include / jsp:forward
5) an action included by tiles / jsp:include / jsp:forward
6) exception raised in a tag class

cases 4,5 were the only real problem as most attempts to handle exceptions resulted in an IllegalStateException or the error page appearing nested within some other page.

solution overview:
all errors go to a single error jsp, this error page locates the root cause exception and places the throwable into the session. The jsp then redirects the browser to a second jsp (using meta-refresh) this ViewError.jsp retrieves the error from the session and displays it.


Details:

1) define a single Error JSP

/WEB-INF/pages/Error.jsp:
**************************************************

<%@ page isErrorPage="true" %>
<%@ page import="org.apache.struts.Globals" %>
<%@ page import="org.apache.commons.lang.exception.ExceptionUtils" %>
<%
//check for tag exceptions that are the 'real' exception
Throwable th = (Throwable) request.getAttribute(Globals.EXCEPTION_KEY);
if (th == null)
{
th = exception;
}
//check exception for root cause using commons-lang ExceptionUtils
Throwable rootCause = ExceptionUtils.getCause(th);
if(rootCause != null)
{
th = rootCause;
}
//best place to log errors is here
session.setAttribute("some_key", th);
%>
<html>
<META HTTP-EQUIV="Refresh" CONTENT="0;url=<%=request.getContextPath() %>/ViewError.jsp">
</html>


***************************************************

2) place this directive within every jsp page:
<%@ page errorPage="/WEB-INF/pages/Error.jsp" %>

3) define the following error-page in web.xml

  <error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/WEB-INF/pages/Error.jsp</location>
  </error-page>

4) Define your ViewError.jsp

The ViewError.jsp contains the exception display code that you would normally place in your error jsp. ViewError.jsp is not a jsp error page (no isErrorPage directive) and you need to include code to retrieve / remove the Throwable from the session:

ViewError.jsp snip:
***************************************************

<%
Throwable ex = (Throwable) session.getAttribute("some_key");
session.removeAttribute("some_key");
%>
//display the error:
   <pre>
   <% ex.printStackTrace(new PrintWriter(out)); %>
   </pre>


***************************************************

I prefer all jsps to be beneath WEB-INF/pages so I define a simple action class to access my ViewError.jsp and redirect to /ViewError.do in my Error.jsp (you can skip this step if your /ViewError.jsp is not beneath /WEB-INF)

I'd be interested to hear if anyone has any better solutions as this still feels a little ugly:

1) all jsps having the error page defined is there no way to set the error-page globally
2) saving and retrieving all 'real' tag exceptions via the request and throwing an intermediate JspException (can be avoided if all tag classes wrap root cause exceptions in the JspException) there seems to be plenty of code like this in struts:
catch (ClassCastException e) {
saveException(pageContext, e);
throw new JspException(blah blah blah);
}
I think the JspException(Throwable) constructor was added in jsp 2.0 so I guess backwards compatability is why this isn't in struts (yet).
3) redirecting browsers, saving and retrieving exceptions in sessions


I still feel like I should be able to define my error handling mechanism in one place (like in web.xml) and job done.

cheers
Nathan


-- Nathan Coast Managing Director Codeczar Ltd mob : (852) 9049 5581 tel : (852) 2834 8733 fax : (852) 2834 8755 web : http://www.codeczar.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to