Notify User from Background Thread

I know there are millions of questions like this, but they all come to having to call UI.getCurrent().access(…) and in my case UI.getCurrent() returns null. The same goes for VaadinSesscion.getCurrent() - also null. I am calling it from a Spring AsyncUncaughtExceptionHandler.

Basically, this is a bean that comes to life every time an exception occurs in an @Async annotated method (such as sending a mail). The handler thread is instantiated by Spring, so I have no way of passing it a Vaadin UI or Component.

So, is it possible to display any kind of error message to the user from a non-Vaadin thread?

There should at least be a way with JavaScript or such.

Yes, UI.getCurrent() returns null when called from background thread for a reason.

Instead of using UI.getCurrent() you should rely on getUI() method the component. This is available both Vaadin 8 as well as in Vaadin 14+

I have example here:

The component knows to which UI it has been attached to. A background thread is not attached to anything, thus UI.getCurrent() or VaadinSession.getCurrent() do not work there.

I have found that the best pattern is to delegate the background thread calls to presenter which then uses excutor service, future etc. like in this example

My code example is Java EE based. However with Spring @Async the principle is the same. @Async itself uses excutor service behind the scenes.

Thank you very much for your comment. I am not 100% sure I understand your example, but I cannot use getUI(), because my background thread has no access to the component it needs to be called on.

My question was meant to be specifically about using Spring’s @Async mechanism, where I have no control over the instantiation of the background thread.

I was wondering, maybe I could throw a custom DOM event from the background thread and catch that in the UI thread?

Why don’t you pass the UI element to the @Async method?

You then can call

component.getUI().ifPresent(ui -> ui.access(() -> {
    // do the UI update here

Yes, that is the correct answer for those many questions very similar to mine :slight_smile:

But in this case Spring calls the method and its signature is:

handleUncaughtException(Throwable ex, Method method, Object... params)

So there is no way to pass a UI component, unless one were to fiddle with the Reflection API…

oh I’m sorry I didn’t read you question good enough. will think about

I solved this by using @Push on my view and adding a method:

protected void onAttach(AttachEvent attachEvent) {
	this.ui = attachEvent.getUI();

So when the user clicks the button that starts the @Async thread I can do something like this:

myService.doAsyncStuff(ui, ...);

And in MyService:

public void doAsyncStuff(UI ui, ...) {

	catch (Exception ex) {
		ui.access(() -> {
			// show error dialog or change UI in another way