You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is related to #20293, but focuses on the DetachEvent rather then the SessionDestroyEvent.
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 in onAttach).
Currently, the only way to make sure a custom onDetach hook is always called is to check every implementation of onDetach of components further down the tree and make sure they don't throw, possibly using try-catch. And there might be third-party components which you don't control directly.
Expected behavior
Ideally, there should be try-finally-like semantics for DetachEvent, 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 to VaadinSession.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.
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 addSuppressed.
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.
Makes sense. I can confirm that this would be enough for our purposes.
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 addSuppressed.
Right, this is exactly what I intended with the second option.
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: