2

when an error occurs inside the application, the user sees the following message:

enter image description here

Is it possible to override it?

I aaded the following:

public class CustomErrorHandler implements ErrorHandler {

    private static final Logger logger = LoggerFactory.getLogger(CustomErrorHandler.class);

    @Override
    public void error(ErrorEvent errorEvent) {
        logger.error("Something wrong happened", errorEvent.getThrowable());
        Notification.show("An internal error has occurred. Please contact support.");
        if (UI.getCurrent() != null) {
            UI.getCurrent().access(() -> {
                Notification.show("An internal error has occurred. Please contact support.");
            });
        }
    }

}

@Component
public class ServiceListener implements VaadinServiceInitListener {

    private static final Logger logger = LoggerFactory.getLogger(LanguageReceiver.class);

    @Override
    public void serviceInit(ServiceInitEvent event) {

        event.getSource().addSessionInitListener(
                initEvent -> {
                    logger.info("A new Session has been initialized!");
                    VaadinSession.getCurrent().setErrorHandler(new CustomErrorHandler());
                });

        event.getSource().addUIInitListener(
                initEvent -> logger.info("A new UI has been initialized!"));
    }

}

@ParentLayout(MainLayout.class)
@AnonymousAllowed
public class ExceptionHandler extends VerticalLayout implements HasErrorParameter<Exception> {

    static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class);

    @Override
    public int setErrorParameter(BeforeEnterEvent event, ErrorParameter<Exception> parameter) {

        logger.error("Error", parameter.getException());

        Label label = new Label(parameter.getException().getMessage());
        add(label);

        return HttpServletResponse.SC_NOT_FOUND;
    }

}

but still unable to override the mentioned error on the screenshot above. Please show how to do this.

alexanoid
  • 24,051
  • 54
  • 210
  • 410

1 Answers1

4

Generally, you need to extend SystemMessages and override getInternalErrorMessage().

Then you can register it using:

YourSystemMessages sysMessages = new YourSystemMessages();
VaadinService.getCurrent().setSystemMessagesProvider(systemMessagesInfo -> sysMessages);

and if you want to reset it to the default one:

VaadinService.getCurrent().setSystemMessagesProvider(DefaultSystemMessagesProvider.get());

In a Spring Boot based application you can register it in any implementation of VaadinServiceInitListener such as:

@Component
public class CustomSystemMessagesInitializer implements VaadinServiceInitListener {

    @Autowired
    private YourSystemMessages sysMessages;
    // You can provide your SystemMessages instance in any way that suits you.

    @Override
    public void serviceInit(ServiceInitEvent serviceInitEvent) {
        serviceInitEvent.getSource()
                .setSystemMessagesProvider(systemMessagesInfo -> sysMessages);
    }

}

Note that serviceInitEvent.getSource() returns the VaadinService instance, so it can be used as the reference as an alternative to VaadinService.getCurrent.

STaefi
  • 4,297
  • 1
  • 25
  • 43
  • Thank you! In which place in Vaadin SpringBoot application it is better to invoke `VaadinService.getCurrent().setSystemMessagesProvider` ? – alexanoid Sep 09 '22 at 11:34
  • 2
    This can be in any implementation of `VaadinServiceInitListener` in your application, as its `serviceInit` method is called just after the initialization of Vaadin Service, and you can use the `serviceInitEvent.getSource()` to obtain the service instance as an alternative to `VaadinService.getCurrent()`. – STaefi Sep 09 '22 at 11:45