Tuesday, June 24, 2008

Error/Exception Handling in JSP - using JSPs or Servlets


Error/Exception Handling in JSP - using JSPs or Servlets


An unrecoverable error while executing a JSP page can be handled by specifying the error JSP pages. These error JSP pages can either be specified in the Deployment Descriptor (web.xml) OR a JSP can have its own error page specified with the errorPage attribute of the page directive. The specifed error pages must have isErrorPage attribute of the page directive set to 'true'. This causes the Web Container to declare a new implicit variable 'exception' which can be used in these error pages (using either scriptlets or custom tages) to display the cause of the error/exception on that error page.


If an error page is specified for a type of exception in the Deployment Descriptor and the page throwing that exception has also got an error page specified then the specified error page takes precedence.


Example: entries in Deployement Descriptor for error handling in JSP


<!-- Reporting an error using a JSP page -->

<error-page>

<exception-type>Fully Qualifies Exception Class</exception-type>

<location>/HandlerJSP.jsp</location>

</error-page>

...


The error JSP page uses isErrorPage attribute so that it can use 'exception' implicit object inside the scriptlets or in custom tags to know about the captured error/exception.


<%@page isErrorPage="true" %>

<HTML>

<HEAD>

<TITLE>Some Error</TITLE>

...


say if the error JSP page wants to know the name of the captured exception class, it can use the following scriptlet for that:-


<%= exception.getClass().getName() %>


Servlets and custom tags may access the captured exception object by calling the method PageContext.getError().


How are the Exceptions Reported?


When an exception is received by the underlying Web Container then it first checks if the JSP page raising that exception has any error page mentioned or not (of course if the exception is raised inside a try-catch block in a JSP the corresponding catch blocks would be examined first). If an error page is specified for the JSP, the 'exception' implicit object is passed to that error page. We'll see later in this article how this object is passed.


If the JSP page doesn't specify any error page and if none of the available catch blocks are able to handle the raised exception (if the exception is raised in try block) then the Web Container starts looking for an error page for that exception in the Deployment Descriptor. If no error page is found for that exception then the Container looks an error page for the exception's superclass and this continue until the Container finds an appropriate error page or until it reaches Throwable class (the topmost superclass of the entire exception handling mechanism in Java).


Can we use Servlets as error handles as well?


Yeah... the syntax is same as what we have for the JSP error pages. One sample entry in the Deployment Descriptor may look like:-


<!-- redirecting an error to a servlet -->

<error-page>

<error-code>404</error-code>

<location>/errorServlet</location>

</error-page>

...


Both the elements <error-code> and <exception-type> can be used with any Web resource (JSP/Servlet) in the application. The element <error-code> specifies the HTML error codes. Thus we see that the errros can be identified either by the Java exception type or by the HTML error codes.


Question: why do we have the implcit object 'exception' of type Throwable and not of the type Exception? (Question raised by one of our regular visitors Lavnish in response to the article - Implicit Objects in JSP >>. Thanks Lavnish for your contribution.)


Answer: Because the JSP page may throw exceptions of type Error as the root cause (though very rarely - may be due to JVM failure, error in a native method, etc.) as well and if we have the type of the implicit object as Exception (instead of Throwable), we would not have been able to capture such an error.


How the implicit object 'exception' is passed?


All the JSP exceptions passed to an error handler (JSP/Servlet) are actually passed via request after being saved by the Web Container in an attribute of the request named "javax.servlet.jsp.jspException". The saved exceptions are of the type javax.servlet.jsp.JspException. The constructors of the class JspException are:-

  • public JspException(java.lang.String msg) - normally for writing a custom message to the server log or maybe for displaying that to the user.
  • public JspException(java.lang.String message, java.lang.Throwable rootCause) - if the 'exception' implicit object is not-null then that is passed as the rootCause parameter.
  • public JspException(java.lang.Throwable rootCause) - a not-null 'exception' implicit object is passed as the parameter.

It's quite evident that the JspException constructor is capable of accepting Throwable type parameter as the rootCause and hence keeping the type of the 'exception' implicit object as 'Exception' will not allow the exceptions of type 'Error' to be specified as the root cause.


Okay... why don't the exceptions are thrown directly? Why do we need to wrap them in a JspException object?


Well... I can think of few probable reasons. One, it gives us a flexibility of creating (and hence throwing) an exception without the occurrence of any error/exception condition. We can use the first constructor of JspException class which requires just a String message and we can use this approach for writing some message to a log or may be to display that message to the user or something of that sort.


Another possible reason to wrap the exceptions in a JspException is to facilitate additional text about the error condition. We may specify some custom message for the exception before throwing that to make the user comprehend the error in a better way. But, you may say that we can specify a detailed message to the constructor of the particular exception class (as Throwable and all its sub types conventionally have a constructor accepting a String parameter). Yeah... we can certainly specify the message that way also. But, the JspException constructor may provide extra details relevant to the particular page as the same exception may have different reasons on different JSPs OR may be in the different sections of a single JSP. The bottom line is that it just gives little extra flexibility :-)


Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.



Share/Save/Bookmark


No comments: