views:

626

answers:

4

I've defined an error-page in my web.xml:

 <error-page>
   <exception-type>java.lang.Exception</exception-type>
   <location>/error.jsp</location>
 </error-page>

In that error page, I have a custom tag that I created. The tag handler for this tag e-mails me the stacktrace of whatever error occurred. For the most part this works great.

Where it doesn't work great is if the output has already begun being sent to the client at the time the error occurs. In that case, we get this:

SEVERE: Exception Processing ErrorPage[exceptionType=java.lang.Exception, location=/error.jsp]
 java.lang.IllegalStateException

I believe this error happens because we can't redirect a request to the error page after output has already started. The work-around I've used is to increase the buffer size on particularly large JSP pages. But I'm trying to write a generic error handler that I can apply to existing applications, and I'm not sure it's feasible to go through hundreds of JSP pages making sure their buffers are big enough.

Is there a way to still allow my stack trace e-mail code to execute in this case, even if I can't actually display the error page to the client?

+1  A: 

Have you tried using the <%@ page errorPage="/myerrorpage.jsp" %> directive?

You also need to use <% page isErrorPage="true" $> in myerrorpage.jsp, then.

I think that may solve your problem. The only problem with that is that you need to include it in every JSP somehow.

Eric Wendelin
I could try that, though I'm not convinced there's a difference between the errorPage="x" attribute and putting it in the web.xml, other than one is page-specific and the other is application-wide.
Josh Hinman
You might give it a shot on one page just to see if it *could* work.
Eric Wendelin
+1  A: 

The errorPage isn't going to be used if you've already started sending data to the client. What I do is use a JavaScript callback to check for an incomplete page and then redirect to the error page. At the beginning of your page in an includes header or something, initialize a boolean javascript variable to false, and register an onload handler to check the state and redirect to an error page.

<script type="text/javascript">
     var pageLoadSuccessful = false;//set to true in footer.jsp
     dojo.addOnLoad(function(){
      if (!pageLoadSuccessful) window.location = "<c:url value="/error.do" />";
     });
</script>

Then in a footer jsp, be sure to set this variable to true:

<script type="text/javascript">
    pageLoadSuccessful = true;//declared in header.jsp
</script>
David Smiley
You probably want to use window.location.replace("<c:url value="/error.do" />") so that the back button still works.
Eugene Katz
+1  A: 

In fact, this particular problem indicates that you were using scriptlets in JSP. This is a bad practice and this particular problem is one of the major reasons for that. You need to move all your business logic to a real java class so that you end up with only taglibs/EL in JSP. In a servlet/filter you can perfectly handle exceptions before forwarding the request to a JSP.

BalusC
Ummm, no. A tag handler can throw an exception and cause this issue. In fact, I believe that was the case here, but it's been over a year and I honestly can't remember.
Josh Hinman
That is then to be considered as a flaw/bug in the tag handler code.
BalusC
A: 

<%@page contentType="text/html" language="java" import="javax.sql." %> <%@page contentType="text/html" language="java" import="java.sql." %> <%@page contentType="text/html" language="java" import="java.io." %> <%@page contentType="text/html" language="java" import="java.lang." %> <% try{ String fr=request.getParameter("from"); String t=request.getParameter("to"); Class.forName("oracle.jdbc.OracleDriver"); Connection con = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE","system","kiran"); String stmt1="select * from app where bno=?"; PreparedStatement pstmt1=con.prepareStatement(stmt1); pstmt1.setString(1,t); ResultSet rs1=pstmt1.executeQuery(); if(rs1.next()) { o ut.println("jkhfdsufyerdsf"); out.println("Class Name:"+rs1.getString(1)+">"); out.println("Maximum Number of seats:"+rs1.getString(2)+">"); out.println(""); } con.close(); }catch(Exception e){ out.println(e.toString()); } %>

kiran