• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Why does Tomcat error handling fire request after response is closed?

 
Greenhorn
Posts: 3
1
Mac Hibernate Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is not a bug per se. I would like to know WHY Tomcat does something it does. I am working with spring web 2.5.5 in this application on Tomcat 7.0.

Scenario: When an exception is thrown in within my application, it is caught by the Spring DispatcherServlet.doDispatch method. That method then calls DispatcherServlet.processHandlerException. processHandlerException iterates through any HandlerExceptionResolvers to try to find a ModelAndView to render. In my case, we have a custom handler that returns a ModelAndView. If a ModelAndView is returned from one of the HandlerExceptionResolvers, processHandlerException then calls WebUtils.exposeErrorRequestAttributes. This adds a status of 200, and the exception to the request. After this, processHanderException returns to doDispatch, and the returned ModelAndView are rendered, which commits the response, directing the user to an error page as expected.

What doesn't make sense to me is what follows next. As control bubbles back up the stack from DispatcherServlet, it ultimately reaches org.apache.catalina.core.StandardContextValve.invoke which is one of Tomcat's "valves" which are executed sequentially prior to delivering a request to a servlet. After control returns to StandardContextValve.invoke it does some checks about request.isAsync and if any errors were applied to the request. Since WebUtils.exposeErrorRequestAttributes (above) applied the exception to the request, it finds that Throwable and calls StandardContextValve.throwable. This method searches for an errorPage (which would have been defined in web.xml) and finds our catch all error page as defined in web.xml. The throwable method then calls the custom method which checks to see if the response is committed (it is in this case). Since it is committed, it calls RequestDispatcher.include. This appears to send the request back through the Dispatcher and ultimately the servlets that handle that errorPage. Even though all the processing is done for that error page, nothing is returned to the user, because the response has already been closed. This is fine, since I already delivered a custom error page to the user.

What I don't understand is: And why does tomcat fire off more processing with RequestDispatcher.include if the response is already committed when spring handled the error? I understand that it does it because it pulled the exception off the request (where Spring placed it after handling the exception). But what benefit is the additional processing after the response has been committed? This question may be better to answer from the spring side of things but I wanted to see if there was some insight on the Tomcat side.

Below is some code snippets that may help understand the problem at hand:

DispatcherServlet.processHandlerException()


WebUtils.exposeErrorRequestAttributes()


Inside StandardContextValve.invoke()

StandardContextValve.throwable()


StandardContextValve.custom()
 
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the JavaRanch, Jesse!

You've certainly done your homework there!

This is the kind of problem that I love to dig into. Unfortunately, it's also the kind of problem that would likely take more time, effort, and access to resources than I can afford as a volunteer.

I did see a few things that puzzled me, though.

The main one was "why are you going through 2 distinct error handlers?" It seems like that if Spring is handling the error, you would normally want Spring to invoke whatever error reporting/recovery you needed and that would be that. Or, at a minimum, that it be instructed not to close the reponse outputstream.

I get the impression that you are intending to use the web.xml error-handling specs to do application logic things and that's probably stretching things. Any page that's generated from web.xml is being controlled by the webapp server, not the webapp itself, and the environment there is somewhat different. Normally, when I use such mechanisms, I'm using them as a last resort or because I'm too lazy to do anything special for the event in question as normal application code. Thus, if I have application error code, it would be self-contained, not bouncing the error up to the server.

I realize this isn't as much help as you'd like, but maybe it will trigger some ideas.
 
Jesse Orloff
Greenhorn
Posts: 3
1
Mac Hibernate Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for taking the time to respond!

So I ended up looking at the latest version of the Spring source code. I figured if I noticed that this was happening, there is a good chance someone from spring noticed as well. Turns out they did. My version of Spring was 2.5.5, and in 2.5.6 they added a simple if then statement to DispatcherServlet.doDispatch. Basically the following

DispatcherServlet in 2.5.5


was changed to

DispatcherServlet in 2.5.6


So, processHandlerException still executes WebUtils.exposeErrorRequestAttributes, but after that view renders, doDispatch calls WebUtils.clearErrorRequestAttributes which basically removes all of those attributes from the request. I'm still not entirely sure why they are exposed in the first place, but I'm assuming it is just in case the render method needs that information.

Inside the SVN changelog for this particular change Spring wrote:

Change deployed in 2.5.6


CORRECTION:

I now know why the change was made in the first place. The change to DispatcherServlet immediately preceeding the above one was:

Change deployed in 2.5.5


And that changes the following



to



Spring 2.5.6 fixes a bug that was introduced in 2.5.5. So the solution in this case is upgrade the Spring jars to the next version, if possible.
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Congratulations!

I just spent a wonderful morning bringing a spring-based webapp up to date myself. It's possible that before I'm done, you will have helped me!

So many people come to the ranch expecting to have their work done for them. You've done most of the work yourself. That deserves a cow!
 
Jesse Orloff
Greenhorn
Posts: 3
1
Mac Hibernate Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you very much! I appreciate your help and encouragement.
 
Tomorrow is the first day of the new metric calendar. Comfort me tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic