IBM Skip to main content
Search for:   within 
      Search help  
     IBM home  |  Products & services  |  Support & downloads   |  My account

developerWorks > Java technology | Web architecture
developerWorks
JSP best practices: Error handling in custom tags
84 KBe-mail it!
Contents:
Investigative redux
An invalid argument example
Overriding an invalid argument
Try, catch, and fix
Wrapping up
Resources
About the author
Rate this article
Related content:
JSP best practices series
Diagnosing Java code series
Take control of your JSP pages with custom tags
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)
Try, catch, and fix error conditions in your custom tags

Level: Introductory

Brett McLaughlin (mailto:brett@oreilly.com?cc=&subject=Error handling in custom tags)
Author, O'Reilly and Associates
19 August 2003

Column iconAs you introduce more interactivity into your custom tags, you also introduce greater potential for error, particularly in the form of invalid arguments. In this installment of JSP pest practices, Brett McLaughlin shows you how to trap and override an IllegalArgumentException at its source.

Up to this point in our discussion of JSP custom tags, we've managed to sidestep the important detail of error handling. Many of the best practices that we addressed in the first half of the series dealt with functionality provided by your JSP container, such as the param, out, and import tags. In these cases, error handling was the domain of the JSP specification and Web server implementation, which means that even if we wanted to do something about it we couldn't.

But the last two installments have focused on custom tag libraries and attributes. We've not only begun adding new functionality to our JSP pages, but we've created attributes that allow JSP authors to interact with our code. Along the way, it's quite possible that we have introduced a new type of error into our JSP pages, or that (at some later point) a page author's mistake could wreak havoc with a tag's code and subsequent output. In either case it has become imperative that we incorporate error-handling into our custom tags.

A note about the examples: All of the example code we'll work with in this installment of JSP best practices builds on the code developed in the previous installment. You should be sure you have successfully completed the setup and coding exercises from the previous installment before continuing here.

Investigative redux
We'll start by retracing our steps through some of the code we developed in the previous installment -- but this time we'll focus on discovering errors (or the potential for errors) in the code.

First off, recall that we added a new attribute, format, to the lastModified tag. This attribute allows page authors to pass in a format string, usable by the java.text.SimpleDateFormat class, that customizes the format of the last-modification date stamp. While this type of interactivity is essential to most JSP pages, it does introduce the potential for errors in our tag.

For example, a page author could easily supply an invalid format string that would result in a nasty error message. To see what this might look like, modify your footer file (or any other JSP page using the lastModified tag) to look like the one shown in Listing 1:

Listing 1. An invalid format string

<%@ taglib prefix="site-utils"
            uri="http://www.newInstance.com/taglibs/site-utils"%>

         </td>
         <td width="16" align="left" valign="top"> </td>
   </tr>
   <!-- End main content -->

<!-- Begin footer section -->
   <tr>
     <td width="91" align="left" valign="top" bgcolor="#330066"> </td>
     <td align="left" valign="top"> </td>
     <td class="footer" align="left" valign="top"><div align="center"><br>
         &copy; 2003 
         <a href="mailto:webmaster@newInstance.com">Brett McLaughlin</a><br>
         Last Updated: <site-utils:lastModified 
           format="PHH:mm a, MM/dd/yyyy"/>
       </div></td>
         <td align="left" valign="top"> </td>
     <td width="141" align="right" valign="top" bgcolor="#330066"> </td>
   </tr>
</table>
<!-- End footer section -->

An invalid argument example
The "P" of the format string "PHH:mm a, MM/dd/yyyy" in Listing 1 has been misplaced, resulting in an invalid formatting string argument. In a Java class, this type of error would cause an IllegalArgumentException to be thrown. In a JSP environment, however, the error would be relayed to the end-user, resulting in an error message similar to the one shown here.

This type of error message is bad enough for a page author to receive and have to untangle; it's much worse if it gets past the author and goes directly to an end user. In the worst-case scenario, the user would be scared off the site by the error message and never return, resulting in loss of publicity, revenue, and reputation -- all of which are extremely important to any company!

Overriding an invalid argument
Fortunately, we can work around this type of error by providing some basic error-handling capability in our custom tags. The most simple form of error handling is to define default (or fallback) behavior to override invalid arguments. In the example of the lastModified tag, we have already created the first part of an error-handling mechanism for this condition, by providing a default format for our time stamp. However, it's better to define the default as a constant, and then refer to the constant, rather than just assigning the string default to a variable. Listing 2 shows how the DEFAULT_FORMAT constant is added and assigned to the format variable:

Listing 2. Setting a default format for the LastModifiedTag

package com.newInstance.site.tags;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;

public class LastModifiedTag extends TagSupport {

    private final String DEFAULT_FORMAT = "MMM d, yyyy";
    private String format = DEFAULT_FORMAT;

    public void setFormat(String format) {
      this.format = format;
    }

    // doEndTag() method, as seen in previous tips
}

Of course, this default value can either be left as it is or modified by the addition of a new format string. If the page author provides an invalid format string, then he will receive an error message. So, in addition to providing default behavior and a mechanism for modifying that behavior, we need to provide a mechanism for reverting to the default behavior in the case of an invalid format string. But before we can fix an error, we need to catch it.

Try, catch, and fix
In any type of error handling, we want to catch the error at its source, which is wherever it first becomes a problem. In this case, the invalid format string will be passed to the SimpleDataFormat constructor, where it will result in an IllegalArgumentException being thrown. So we place a try/catch block on the constructor, as shown in Listing 3:

Listing 3. A try/catch block for an invalid format string

package com.newInstance.site.tags;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;

public class LastModifiedTag extends TagSupport {

    private final String DEFAULT_FORMAT = "MMM d, yyyy";
    private String format = DEFAULT_FORMAT;

    public void setFormat(String format) {
      this.format = format;
    }

    public int doEndTag() {
      try {
        HttpServletRequest request = 
          (HttpServletRequest)pageContext.getRequest();
        String path = pageContext.getServletContext().getRealPath(
          request.getServletPath());
        File file = new File(path);

        DateFormat formatter;
        try {
          formatter = new SimpleDateFormat(format);
        } catch (IllegalArgumentException e) {
          formatter = new SimpleDateFormat(DEFAULT_FORMAT);
        }

        pageContext.getOut().println(
          formatter.format(new Date(file.lastModified())));
      } catch (IOException ignored) { }
      return EVAL_PAGE;
    }
}

Note that lastModified output now reverts to the default format string in the event of an IllegalArgumentException being thrown. You can test this out by recompiling the tag with the new code, restarting your servlet container, and accessing the page with the invalid date format. Rather than a nasty stack trace, you should see a normal-looking footer, displaying the last-modification date and time in the format specified by DEFAULT_FORMAT.

Wrapping up
Hopefully this tip has shown the importance of including error-handling mechanisms in your custom tags. Every new custom tag (and attribute) represents a unique extension of the JSP platform, and so you must also provide a unique solution to any problem that may arise out of that extension.

For a follow-up exercise to what you've learned here, try retracing your steps through some of the custom tag libraries you've already written. Now that you've developed an eye for it you'll likely discover at least one or two error conditions in need of correction. Just remember the simple try-catch-fix technique you learned here: locate the error at its source, apply a mechanism to catch it, and then provide some type of behavior to override it.

In the next installment of JSP best practices, we'll complete our discussion of custom tag libraries by talking about packaging. You'll learn how to package one or more custom tag libraries in a JAR file for easier maintenance, distribution, and Web-container installation. Until then, I'll see you online!

Resources

About the author
Photo of Brett McLaughlinBrett McLaughlin has been working in computers since the Logo days (remember the little triangle?). He currently specializes in building application infrastructure using Java and Java-related technologies. He has spent the last several years implementing these infrastructures at Nextel Communications and Allegiance Telecom Inc. Brett is one of the co-founders of the Java Apache project Turbine, which builds a reusable component architecture for Web application development using Java servlets. He is also a contributor of the EJBoss project, an open source EJB application server, and Cocoon, an open source XML Web-publishing engine. Contact Brett at brett@oreilly.com.


84 KBe-mail it!

What do you think of this document?
Killer! (5) Good stuff (4) So-so; not bad (3) Needs work (2) Lame! (1)

Comments?



developerWorks > Java technology | Web architecture
developerWorks
  About IBM  |  Privacy  |  Terms of use  |  Contact