flow
flow copied to clipboard
Exception in beforeEnter followed by browser back in @PreserveOnRefresh view using @RouteScope causes usage of different instances of @RouteScoped bean
Description of the bug
When using @PreserveOnRefresh views with @RouteScoped beans, we encounter a problem when trying to go back to a valid state after an exception in beforeEnter().
In our setup we have a view in @RouteScope. The view (some kind of wizard) loads components (wizard steps) that are spring beans in @RouteScope. The view and those components share a @RouteScoped context bean (data of the wizard).
In this setup (see simple sample attached), when executing the following steps
- Open view with valid parameters (http://localhost:8080/parent) -> view and component(s) show correctly
- Modify URL with invalid parameters (http://localhost:8080/parent?err=123)
(
beforeEnter()throws Exception) ->ErrorNotificationofErrorHandleris shown (or ErrorPage) - Use browser back button to return to step 1
=> the view (ParentView) and the selected component (e.g. ChildA) now use different context instances, what is not what we expect. The ParentView instance get's preserved and contains the old context instance but the route scope was destroyed and thus the children get a new context instance injected.
For the wizard use case it is vital, that view and components (i.e. wizard, wizard-steps and services) use the same context bean.
We have tried with and without navigation to ErrorPage as documented in https://vaadin.com/docs/latest/flow/advanced/custom-error-handler#error-parameter-views-for-non-navigation-exceptions.
In both cases step 3 shows different context bean instances used.
Please note the following:
- In the example application
ChildAis a vaadin ui component that get's the scoped context injected. In the real world application the setup is more complex and the scoped context will also be injected as a scoped proxy into service beans. Thus it won't help to move the creation ofChildAintoParentView. - If there is no error / no exception thrown in
beforeEnter()the back-navigation works as expected and bothParentViewandChildAhave access to the same context instance.
Expected behavior
The @RouteScoped context instance used in the view and the spring components is the same even when an error occured in beforeEnter(). For our usecase consistency is more important than keeping the old instance. That said it would be okay to create re-create the view with an empty/new context object aslong as it is the same instance than the one active in @RouteScope.
Minimal reproducible example
Versions
- Vaadin / Flow version: 24.7.6
- Java version: 17
- OS version: Linux
- Browser version (if applicable): n/a (browser independent)
- Application Server (if applicable): Apache Tomcat
- IDE (if applicable): n/a
The issue seems to be fixed by #21602 that will be released in 24.7.7. I tested the provided example with 24.7-SNAPSHOT and after pressing the back button, the UUID on the page is the same for both parent and child components.
Vaadin 24.7.7 to be released soon.
A collegue of mine has successfully tested the changes. As far as we are concerned the issue can be closed.