-
Notifications
You must be signed in to change notification settings - Fork 181
UI added to session before fully initialized #21460
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
Comments
This sounds like a Flow issue not specific to a certain component, so I'll transfer it to the Flow repository. |
The problem is that you are trying to use UI init listener to get routing data, whereas the routing is not yet ready/completed. This approach is unreliable because this may work when a navigation completes and may throw if not. Would it be an option for you to use |
We want to poll/update all UIs (or all relevant UIs based on some criteria) when certain changes happen to backing session or user related configurations. The issue is that while we can get the list of UIs from the session, we have no idea if they are fully initialized yet or not, and no way to tell. We assumed UIs must be fully initialized by the time the In taking another look at our code (I finally have a 2nd developer! Yay!), I see however we are doing this, as noted in the issue: 'VaadinSession.getCurrent().getUIs().forEach(ui->ui.access(()->UI::getCurrentView));' However, I think perhaps
|
Description
``It is possible to hit an
IllegalStateException
when performing an action on session UI instances because a UI is in the list but hasn't finished initialization."Routing is not in use or not yet initialized. If you are not using embedded UI, try postponing the call to an onAttach method or to an AfterNavigationEvent listener."
The problem is, if you have multiple tabs/windows in your session, and a somewhat long-running (maybe just a couple seconds)
UIInitListener
, then you can take an action that opens a new tab or window with an application URL, which creates a new UI instance, and then in the original window perform some action that triggers a loop through session UIs, perhaps to message each one, poll state, etc., and get this error.The error comes from
BootstrapHandler.createAndInitUI(...)
. It has this code at the end:As you can see, the error comes because the router hasn't been initialized yet when the UI is added to the session UI Collection. That collection can be iterated on immediately by another request. The time window is controlled by the duration of the custom listeners.
It could be as simple as not adding the UI to the session until after the router is done, or it may need some sort of two-phase update, if the UI needs to be found in the session in the contract of init listeners or the implementation of router init.
Expected outcome
I expect
VaadinSession.getCurrent().getUIs().forEach(ui->ui.access(()->UI::getCurrentView));
to not throwIllegalStateException
.Minimal reproducible example
See the steps to reproduce
Steps to reproduce
The problem is, if you have multiple tabs/windows in your session, and a somewhat long-running (maybe just a couple seconds)
UIInitListener
, then you can take an action that opens a new tab or window with an application URL, which creates a new UI instance, and then in the original window perform some action that triggers a loop through session UIs, perhaps to message each one, poll state, etc., and get this error.So create an app with a view with a link to itself.
Add a
UIInitListener' that just sleeps 5 or 10 seconds. Add a button that tries to enumerate the UIs and call getCurrentView:
VaadinSession.getCurrent().getUIs().forEach(ui->ui.access(()->UI::getCurrentView));`Run the app.
control-click the link to open it in a new tab, then click the button to trigger the enumeration.
Environment
Vaadin version(s): 24.7.4
OS: N/A
Browsers
Issue is not browser related
The text was updated successfully, but these errors were encountered: