Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How to handle an Exception thrown in a Scriptlet in a .Tag File

 
Jeff Cerwinske
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've just started to using .tag files to componentize parts of a JSP application, as well as clean some scriptlets out of the main .jsp file, and I've begun to run into some issues, particularly when there is an error that occurs in the code contained in the tag file.

I have an error.jsp page, that uses the directive <%@page isErrorPage="true" %>
On my main .jsp page (wizard.jsp), it uses the directive <%@ page errorPage="/common/jsp/error.jsp" %> and indeed correctly references the error page.

In wizard.jsp I created the following scriptlet in order to force an exception:
<%
if(true)
throw new SQLException("Message");
%>

In this case, when I try to load the page, it correctly forwards the exception to the error.jsp page which is displayed (as opposed to displaying the wizard.jsp page).


Let's try another case though. Lets say I have a tag library referenced in my wizard.jsp and prefixed "my", with a tag called "item" (<my:item/>)
This tag is defined in /WEB-INF/tags/item.tag. Now, I've removed the above scriptlet from the wizard.jsp page, and put it instead in the item.tag file, and then make reference to this tag file in my wizard.jsp.

Now, I try to load wizard.jsp. Now, instead of being forwarded to the error page due to the exception, the error.jsp page is rendered AS THE CONTENT OF THE TAG. and placed directly IN THE wizard.jsp. When I look at the page source via the browser, the markup of wizard.jsp that precedes that tag is given as normal, then <my:item/> is replaced by all of the markup of the errorpage, then STOP. The markup of wizard.jsp that occurs BELOW the <my:item/> doesn't exist.

My question: How do I get the act of an exception thrown in the body of a tag file to actually forward me to the error.jsp page, instead of rendering the error page as the content of the tag?


Followup: If I remove the errorPage page directive in my wizard.jsp file, the exception is then handled by the servlet, and dumped to a log:

Stacktrace:
org.apache.jasper.JasperException: An exception occurred processing JSP page /wizard/wizard.jsp at line 23

20: <div class="title">
21: Wizard
22: </div>
23: <my:item/>
24: </body>
25:
26: </html>


It doesn't tell me where the error in the code really is. It just tells me where in the .jsp file the tag which contains the error is called, as opposed to where in the .tag file exception is actually thrown. If you have nested tags, this is especially useless, as you have no idea in which child, or grandchild tag the error actually is.

Can anyone help me wrap my head around proper exception handling when using tag files? It just seems silly that it seems to kind of break the expected behavior of .jsp exception handling...

 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65111
89
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dump the error page directives in your JSPs and configure error handling in the deployment descriptor.

There, define a servlet to centrally handle errors in a deterministic fashion, forwarding to the JSP marked as the error page as necessary.
 
Jeff Cerwinske
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply! Was just able to try what you've suggested, but It's not quite working for me.

Here is my intial servlet definition:
<servlet>
<servlet-name>WizardServlet</servlet-name>
<servlet-class>my.WizardServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>WizardServlet</servlet-name>
<url-pattern>/Wizard</url-pattern>
</servlet-mapping>


As a test case, I've added to my web.xml:

<servlet>
<servlet-name>ErrorServlet</servlet-name>
<servlet-class>my.ErrorServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>ErrorServlet</servlet-name>
<url-pattern>/Error</url-pattern>
</servlet-mapping>

<error-page>
<error-code>404</error-code>
<location>/Error</location>
</error-page>

<error-page>
<exception-type>java.sql.SQLException</exception-type>
<location>/Error</location>
</error-page>

<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/Error</location>
</error-page>

Now, if I try to enter a bad URL, such as http://localhost:80/MyAppName/Wizard/blah, the 404 is caught and control is redirected to the ErrorServlet, indicating that at least my <error-page> and <servlet> for the error are correctly defined. However, in my wizard.jsp, when the

<%
if(true)
throw new SQLException("Message");
%>

scriptlet is enountered, I do NOT end up in the ErrorServlet, but back in the WizardServlet that directed the user to wizard.jsp (the servlet which handles /Wizard requests)

Ok I did some deeper looking, and am going to continue in the next post to hopefully keep it semi-readable....
 
Jeff Cerwinske
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, I did some more digging, and perhaps this might help explain what's going on.

I've got a a wrapper method defined as follows:

public static void forwardTo(String page, ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
servletContext.getRequestDispatcher("/" + page).forward(request, response);
}



I'm using this method for all forwards from the servlet to a JSP page.

Basically, when I try to go to http://localhost:80/MyAppName/Wizard, I enter the wizard servlet, which determines via session variables that it is the user's first visit to the app, sets up some session attributes, and then forwards:

forwardTo("wizard/wizard.jsp", this.getServletContext(), request, response);

wizard.jsp has the offending, SQLException raising scriptlet. When raised, control does NOT get handed to the ErrorServlet, as I expected based on the error handling specified in the web.xml...

Instead, a ServletException is caught by the try/catch block that surrounds the forwardTo() call.


Here I can certainly catch and log that error, but it's not helping with my original question. This same behavior happens when I move the offending scriptlet into a tag file which is used in wizard.jsp. I can log the error, but I get the same, unhelpful stacktrace as before, with NO information about where in the tag itself, that the error is raised...

Stacktrace:
org.apache.jasper.JasperException: An exception occurred processing JSP page /wizard/wizard.jsp at line 23

20: <div class="title">
21: Wizard
22: </div>
23: <my:item/>
24: </body>
25:
26: </html>

 
Jeff Cerwinske
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Running Tomcat 6, btw...
 
Jeff Cerwinske
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bear Bibeault wrote:Dump the error page directives in your JSPs and configure error handling in the deployment descriptor.

There, define a servlet to centrally handle errors in a deterministic fashion, forwarding to the JSP marked as the error page as necessary.


I've just read the following:

""The error page mechanism described does not intervene when errors occur in servlets invoked using the RequestDispatcher. In this way, a servlet using the RequestDispatcher to call another servlet has the opportunity to handle errors generated in the servlet it calls."

Wait....So basically the forwarding of a request to a .JSP throws all the error handling mechanisms out the window? Seems kind of silly...
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic