On Sun, 16 Jan 2005 12:10:37 +0800, Nathan Coast <[EMAIL PROTECTED]> wrote: > 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> >
If we do (3) I believe we don't have to (2) in each and every jsp. Isn't it? > 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] > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]