[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Beginner question: jsp error pages




Yeah, this makes sense... Thank you!!!

Milena


----- Original Message ----- 
From: Jeff
To: Milena Khlabystova ; Herb Uhrig ; ajug-members@www.ajug.org
Sent: Wednesday, June 18, 2003 4:34 PM
Subject: Re: Beginner question: jsp error pages


I don't think this is a bug.  I'm pretty sure the implicit "exception"
variable is a JSP-specific thing, and therefore not available when a
servlet throws an error, since javax.servlet.jsp.HttpJspPage is
ultimately a subclass of Servlet, and the superclass will not support
the subclass's functionality.  I think the implicit exception object
available when a JSP page throws an exception is backed by the EXCEPTION
property of the javax.servlet.jsp.PageContext class
(file:///C:/Tomcat4/webapps/tomcat-docs/servletapi/javax/servlet/jsp/Pag
eContext.html if you have Tomcat installed), and the PageContext is not
available when a servlet throws an exception, because it's not a JSP
page, but the parent class of servlet.

However, there is still a good way to do what you want, the servlet
specification defines a standard way for servlets to report exception
data to error handlers, in the form of attributes that the servlet
container is required to populate with the relevant information prior to
forwarding an error the error handling resource.  There are six you can
count on, some are a bit redundant, but they are:
javax.servlet.error.status_code, javax.servlet.error.exception_type (can
be got from javax.servlet.error.exception), javax.servlet.error.message
(can be got from javax.servlet.error.exception),
javax.servlet.error.exception, javax.servlet.error.request_uri,
javax.servlet.error.servlet_name.

If you grab these standard attributes from the request scope on your
error-handling JSP page, it will correctly process errors from either
other JSP pages or servlets, since a JSP page is a direct descendant of
Servlet, it support both the servlet way of doing it, as well as the
implicit exception object that JSP provides.  In my opinion, Sun added
this exception object (which is somewhat redundant given the same
information can be obtained from the javax.servlet.error.exception
attribute of the request object) as an ease-of-use thing, in keeping
with the "JSPs are easier to code than Servlets" line of thinking.

Anyhow, here's an error handler JSP that I use all the time that works
great for exceptions thrown by either other JSP pages or servlets.  It
does contain direct scriptlet code, and to be really pure, that stuff
should probably all be moved out into custom tags, so the JSP is
presentation only, but I haven't gotten around to that :-(

--- snip ---
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<% String appName = getServletContext().getServletContextName(); %>

<html>
<head>
 <title><%= appName %>: Error</title>
 <link href="<%= request.getContextPath() %>/style/app_styles.css"
rel="stylesheet" type="text/css">
</head>

<body>

<p class="PageTitle"><%= appName %>: Error</p>

Unhandled Exception (<%=
request.getAttribute("javax.servlet.error.status_code") %>):
<%= request.getAttribute("javax.servlet.error.exception_type") %>

<p class="ErrorMessage"><%=
request.getAttribute("javax.servlet.error.message") %></p>

<p>ocurred while accessing: <%=
request.getAttribute("javax.servlet.error.request_uri") %>
(servlet: <%= request.getAttribute("javax.servlet.error.servlet_name")
%>)</p>

<pre>
<%
Throwable e =
(Throwable)request.getAttribute("javax.servlet.error.exception");
StackTraceElement[] stack = e.getStackTrace();
for(int n = 0; n < Math.min(5, stack.length); n++) { %>
 <%= stack[n].toString() %>
<% }

if(e instanceof ServletException)
 e = ((ServletException)e).getRootCause();
else
 e = e.getCause();

if(e != null) { %>
 <hr size="1"><b>root cause:</b> [<%= e.getClass().getName() %>] <%=
e.getMessage() %>
 <% stack = e.getStackTrace();
 for(int n = 0; n < Math.min(5, stack.length); n++) { %>
  <%= stack[n].toString() %>
 <% }
} %>
</pre>

</body>
</html>
--- snip ---