9.4 Error Handling

I l @ ve RuBoard

Even a perfectly designed application can fail now and then, through no fault of its own; external resources such as databases or other servers can become inaccessible due to hardware or network problems, or simply because of regular maintenance activities. It's important that the web application deals with such situations, as well as problems caused by unexpected user input, in an appropriate manner. This section provides ideas for how to do so efficiently .

9.4.1 Use Common Error Pages for the Whole Application

The JSP page directive's errorPage attribute can be used to specify a page to be invoked when an error occurs while processing the page. The page can be a static HTML file, a servlet, or a JSP page. A JSP page used as an error page (designated as such by the page directive's isErrorPage attribute) has access to a Throwable instance that represents the error through the implicit exception scripting variable, or through the EL expression ${pageContext.exception} .

While this mechanism might be suitable for a small application using only JSP pages, it's not appropriate for an enterprise application using a combination of servlets, filters, and JSP pages. Using a shared error handler for all these component types lets you better control error handling and fine-tune it in one place when needed. To use a global error handler, do not use the errorPage attribute in the JSP pages. Instead, declare an error handler in the web application deployment descriptor (the web.xml file):

 <web-app>    . . .    <servlet>     <servlet-name>errorHandler</servlet-name>     <servlet-class>       com.ora.jsp.servlets.ErrorHandlerServlet     </servlet-class>     <init-param>       <param-name>errorPage</param-name>       <param-value>/shared/error.html</param-value>     </init-param>   </servlet>    . . .    <error-page>     <exception-type>java.lang.Throwable</exception-type>     <location>/errorHandler</location>   </error-page>    . . .  </web-app> 

Here, I define a servlet as the error handler for all types of exceptions; Throwable is the base class for all exception, so all more specific exceptions match this single error handler declaration. You can also define separate error handlers for different exception types (the best match wins), as well as error handlers that are triggered by HTTP response status codes instead of exceptions.

Instead of a servlet, you can specify a static HTML page or JSP page as the error handler. A servlet has the advantage in that it can easily capture information about the error and then forward it to a page (a static page or a JSP page) that just describes the problem in user-friendly terms, so that's what I recommend.

If you still like to use a JSP page instead of a servlet, be aware that the implicit exception scripting variable (and the corresponding value available through an EL expression) that is assigned a reference to Throwable when the page is invoked because of an errorPage attribute in another JSP page is not assigned a value when the JSP page is invoked as a global error handler based on a web.xml declaration. This is due to an unfortunate naming mismatch between the Servlet 2.3 and JSP 1.2 specifications: the JSP specification says that a request attribute named javax.servlet.jsp.jspException is used for passing Throwable to the error page, while the servlet specification defines the javax.servlet.error.exception request attribute for the same thing when passing it to a global error handler. To get access to Throwable in a global JSP error handler, you must therefore extract it from the request attribute yourself ”for instance, using this JSTL <c:set> action:

 <c:set var="problem"    value="${requestScope['javax.servlet.error.exception']}" /> 

9.4.2 Capture Enough Information to Fine-Tune the Application

With a common error handler for both servlets and JSP pages, it's easy to log information about runtime errors. By capturing information detailing where the error occurred, the precise problem, and all (or at least most of) the dynamic data available at the time, you can fine-tune the application to deal more gracefully with common, predictable runtime errors.

A global error handler declared with the <error-page> element in the web.xml file has access to all information of interest. First of all, it can get information about which component failed and the exception that was thrown through the following request attributes.

Request attribute name

Java type



The HTTP status code that triggered a handler declared as a status code handler


The exception that triggered a handler declared as an exception handler


The URL for the request that triggered the handler


The declared name for the servlet or JSP page that triggered the handler, or the class name if no name is declared

In addition to the information available through these request attributes, you should also consider logging request parameter values and application-dependent request, session, and context attributes.

9.4.3 Consider Using <c:catch> to Handle Recoverable Errors

If you discover that a JSP page frequently throws an exception due to unexpected input or because an external resource is occasionally unavailable, you should consider catching the exception in the JSP page using the JSTL <c:catch> action. You can then deal with the problem in a more user-friendly way. Consider this example, in which a JSP page includes an external resource that is not essential for the application's main functionality:

 <table bgcolor="lightblue">   <tr>     <td>  <c:catch var="error">  <c:import url="http://www.gefionsoftware.com/jspnews.jsp" />  </c:catch>  <c:if test="${error != null}">         Sorry, the news feed is temporarily unavailable.       </c:if>     </td>   </tr> </table> 

By catching the potential exception in the JSP page, a response is generated even when the external resource is unavailable.

I l @ ve RuBoard

The OReilly Java Authors - JavaT Enterprise Best Practices
The OReilly Java Authors - JavaT Enterprise Best Practices
Year: 2002
Pages: 96

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net