Accessing application window when uncaught exception occures

Hello everybody.

I am interested in getting reference to application window (the one which parent == null) when uncaught exception occures. In section 4.9 of Book of Vaadin there is a way by overriding public void terminalError(Terminal.ErrorEvent event) method of Application class. The way of getting application window is by calling getMainWindow() method - obviously.

But my question is:
is there any other way to achieve this reference?

I already made tries which implementation is almost identical with terminalError method declared in super class by checking using instanceof the owner of the exception and then calling getCause() on Vaadin related exceptions. Then I get reference to AbstractComponent and I can access window by combining calls to getWindow() and/or getParent().

This works heh, almost good. I can get the reference to application window. But in my case situation looks like:
I want to delete item from DB. Before delete is executed I show Yes-No dialog to the user. After that deleting item is executed. When the process fails of some reason, I get uncaught exception in terminalError method, then I get access to AbstractComponent (what in this case is Vaadin button “Yes”) then I want to get top level window (parent == null) and what I get is the reference to dialog box itself. This happens because after pressing “Yes”, dialog window is removed from parent.

So repeating my question:
is there any other way to get the top level (application) window in terminalError method without calling getMainWindow()?

Cheers
Radek

There are a few situations where the terminalError() method can be called, including file resource fetching, download stream creation as well as application servlet level issues for requests which might not concern any window.

The cases you are interested are probably related only to the call from AbstractApplicationServlet.service() calling handleServiceException(). You could take a look at the (private) code there that looks up the window, but probably it does not pass enough information to the error handler to duplicate the logic.

Then again, why let the exception propagate all the way here instead of catching and handling it elsewhere?

Yes, this is the proper and logic way to handle exceptions of course.

There are many ideas about security in web applications including JAAS etc. I have a situation where calling bean methods throws security exceptions (interceptor throws it). Then I had to catch them in hundreds of places. This security exception(s) are Runtime exceptions so I can even “forget” to do it… Using terminalError method I could catch these security exception and put Notification “You don’t have rights to do this action” instead of hundreds catches.

One idea to get around this - a bit complicated and ugly a hack, but might work without modifying any core classes:

Use a TransactionListener and store the application and request instances in a ThreadLocal, and make sure you clear them at the end of the request. Then in your error handler, check if they are set and duplicate the bits of logic in AbstractApplicationServlet.service() and getApplicationWindow() that get the window.

This way, you should be able to get the correct window (for normal UIDL requests) also in a multi-window application. If the fields are not set or you do not get a window instance, then the request probably do not concern a specific window but e.g. an upload operation or a general problem.

Thanx. I was thinking about storing somehow a pair: application/window and thread and then get the right application window but I didn’t figure out to use TransactionListener. Good point.