flow icon indicating copy to clipboard operation
flow copied to clipboard

Exception in beforeEnter followed by browser back in @PreserveOnRefresh view using @RouteScope causes usage of different instances of @RouteScoped bean

Open StefanPenndorf opened this issue 5 months ago • 2 comments

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

  1. Open view with valid parameters (http://localhost:8080/parent) -> view and component(s) show correctly
  2. Modify URL with invalid parameters (http://localhost:8080/parent?err=123) (beforeEnter() throws Exception) -> ErrorNotification of ErrorHandler is shown (or ErrorPage)
  3. 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:

  1. In the example application ChildA is 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 of ChildA into ParentView.
  2. If there is no error / no exception thrown in beforeEnter() the back-navigation works as expected and both ParentView and ChildA have 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

vaadin24test_20250606.zip

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

StefanPenndorf avatar Jun 06 '25 12:06 StefanPenndorf

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.

mcollovati avatar Jun 16 '25 06:06 mcollovati

Vaadin 24.7.7 to be released soon.

mshabarov avatar Jun 17 '25 10:06 mshabarov

A collegue of mine has successfully tested the changes. As far as we are concerned the issue can be closed.

StefanPenndorf avatar Aug 19 '25 13:08 StefanPenndorf