Catching navigation errors globally

Is there a standard way to catch all exceptions from the UI, particularly during UI instantiation? The exception occurs because of backend issues, and I could write a try-catch block in the constructor for all exceptions, but a nice error page would be better for user. I’m building an application with Vaadin 24.8.6.

ERROR 69680 --- [nio-8080-exec-8] c.v.flow.router.InternalServerError      : There was an exception while trying to navigate to 'chat'

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.example.webui.views.chat.ChatView': Failed to instantiate [com.example.webui.views.chat.ChatView]: Constructor threw exception

Here are the links to the relevant documentation.

2 Likes

Just a random note of best practice: don’t call backends in your constructor, use beforeEnter or afterNavigation hooks

1 Like

Curious, why not onAttach ?

Personal preference. Additionally the route lifecircle has dedicated error handling from a framework perspective, therefore I would recommend to “hook yourself into it”. onAttach might be fine for “components”, but IMHO not for routes

IMO onAttach is the wrong abstraction level. It’s fired when a Component is attached to a UI. While it happens to get fired when you navigate to a view, there’s no requirement for the case to be like that - and its ordering might be inconvenient, or change at an unknown point. The framework provides you specific methods react to navigation events, so if you want to do things before leaving, before entering, or after navigation, you should use those.

1 Like

Right, but for the actual construction of the page, adding components etc then onAttach is the correct method ?

The constructor should be fine for most typical cases. onAttach is useful if you need to do something related to the attaching of the component, so something that requires that the UI is present.

Another useful scenario for onAttach is something that pairs with onDetach. For example, if you need to lock some kind of resource while the view is open, then it makes sense to acquire the lock in onAttach and release it in onDetach.

Constructors can be problematic in a clustered setting, as they are not executed when the class is deserialized (we have clustered setup with kubernetes-kit). That’s why we avoid it and do everything in onAttach.

Shouldn’t you rather do deserialization-specific initialization in readObject?

Using readObject would make the whole serde dance even more incomprehensible. It’s hard enough as it is already to make people pay attention to the fact that all objects that could end up in the session must be Serializable.

Anyway, there are serialization improvements appearing on the JDK horizon: Serialization - A New Hope – Inside.java so maybe one day it will work as people expected it from the beginning.

1 Like

I guess then in your case, onAttach is a suitable workaround (especially if afterNavigation doesn’t work for some reason). Looking forward to those serialization improvements!