-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DetachListeners and onDetach hooks are not called when an exception is thrown during detach of contained components #20577
Comments
Agreed. These types of listeners should be resilient so that application code can rely on those being called when appropriate even if other parts of the application misbehaves. But this mainly applies for the types of listeners that are typically used for cleanup, e.g. component detach, session destroy and service destroy. There's no need to put the same effort into making e.g. click listeners resilient. The best solution would probably be to collect all exceptions from a the whole recursive detach operation and throw them once the detach is completed. If multiple exceptions are caught, then we should throw the first one but attach all the others using |
Makes sense. I can confirm that this would be enough for our purposes.
Right, this is exactly what I intended with the second option. |
Makes sense to do #20577 (comment) and fix the linked issue #20293 in one go, but let us first investigate what the implementation could be. The concern is that it can require a new method or behaviour change. Overall, limiting the scope to only detach/destroy listeners and re-throw the original exception sounds as a good compromise. |
Looks like for |
Related to #20577 Co-authored-by: Teppo Kurki <[email protected]>
Related to #20577 Co-authored-by: Teppo Kurki <[email protected]>
Related to #20577 Co-authored-by: Teppo Kurki <[email protected]> Co-authored-by: Marco Collovati <[email protected]>
Great that this has been fixed, thanks! 👍 Just out of curiosity: Why did you choose to pass exceptions to the ErrorHandler instead of collecting and rethrowing them? Is it because the ServiceDestroyListener already did something similar, as pointed out by @tepi? |
Description of the bug
This is related to #20293, but focuses on the
DetachEvent
rather then theSessionDestroyEvent
.When a component is removed from the view, the whole component subtree will be notified bottom-up about this
DetachEvent
. If one of the detach hooks or listeners of "lower" components throws an exception, the components higher up the tree will never get notified.This can lead to resource leaks, because
onDetach
is a good place to release resources (which are typically aquired inonAttach
).Currently, the only way to make sure a custom
onDetach
hook is always called is to check every implementation ofonDetach
of components further down the tree and make sure they don't throw, possibly usingtry-catch
. And there might be third-party components which you don't control directly.Expected behavior
Ideally, there should be
try-finally
-like semantics forDetachEvent
, meaning that the corresponding hooks and listeners should always be called, even if an exception is thrown from detach hooks further down the tree.As I said in #20293, it shouldn't be the responsibility of these other components to make sure another component higher up the tree can clean up its resources. Instead, this should be the responsibility of that component itself, and Vaadin should provide the mechanisms to make that possible.
I am not sure what exactly should happen when an exception is thrown, though. I guess a good start is to wrap every invocation of a detach hook or listener in a
try-catch
block. In the catch block, one option would be to simply pass all exceptions toVaadinSession.getErrorHandler()
. Another option would be to remember the first exception and to add all following exceptions as suppressed to it, so the first exception can be rethrown once the whole detach process has completed.Minimal reproducible example
onDetach
will not print anything to the console, nor will it show the notification.Versions
The text was updated successfully, but these errors were encountered: