vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
603 stars 165 forks source link

Vaadin ExceptionHandling behaves differently with exceptions in lazy-loading-dataproviders #9573

Open hoffmaw opened 3 years ago

hoffmaw commented 3 years ago

Description of the bug / feature

Exceptionhandling is different wheather the Exception occures before or after loading of the page finished and wheather the Exception occures inside a fetch-method of a lazy-loading-dataprovider or not.

At startup outside a LLDP: the Exception is handled by our ErrorHandler extending InternalServerError

After startup outside a LLDP: the Exception is handled by our ErrorHandler implementing ErrorHandler

After startup inside a LLDP: the Exception is passed to our ErrorHandler implementing ErrorHandler in VaadinService.handleExceptionDuringRequest() but then a Notification is displayed in the GUI: "Internal error Please notify the administrator. Take note of any unsaved data, and click here or press ESC to continue."

At startup inside a LLDP: the Exception is passed to our ErrorHandler implementing ErrorHandler in VaadinService.handleExceptionDuringRequest() but the check for RequestType.UIDL fails and a stacktrace is displayed in the browser: HTTP ERROR 500 javax.servlet.ServletException: javax.servlet.ServletException: com.vaadin.flow.server.ServiceException

We would like to have all Exceptions handled by our Handlers so error-display is consistent, no Notifications or Stacktraces.

Minimal reproducible example

see attached modifyed vaadin example project

Versions:

- Vaadin / Flow version: 14.4.0
- Java version: 8
- OS version: Win10
- Application Server: jboss-eap-7.1.6.CP, also reproducalbe on jetty

errorhandling.zip

mvysny commented 1 year ago

The "After startup inside a LLDP:" case can be reproduced in a skeleton starter as well, and is still present in Vaadin 14.9.4:

public class MainView extends VerticalLayout {

    private static final Logger log = LoggerFactory.getLogger(MainView.class);

    public MainView() {
        VaadinSession.getCurrent().setErrorHandler((ErrorHandler) event -> {
            log.error("Err", event.getThrowable());
            Notification.show("Error happened!!!!! " + event.getThrowable());
        });
        add(new Button("Fail correctly via ErrorHandler", e -> { throw new RuntimeException("Simulated"); }));
        add(new Button("Fail in DP", e -> {
            // the exception thrown by the DataProvider still goes through ErrorHandler, but the Notification is not shown;
            // instead, the "Internal error Please notify the administrator. Take note of any unsaved data, and click here or press ESC to continue." dialog is shown.
            final Grid<String> grid = new Grid<>();
            grid.addColumn(it -> it).setHeader("it");
            grid.setDataProvider(new AbstractBackEndDataProvider<String, Void>() {
                @Override
                protected Stream<String> fetchFromBackEnd(Query<String, Void> query) {
                    throw new RuntimeException("Simulated");
                }

                @Override
                protected int sizeInBackEnd(Query<String, Void> query) {
                    throw new RuntimeException("Simulated");
                }
            });
            add(grid);
        }));
    }
}

Screenshot:

Screenshot from 2023-01-17 10-23-40

mvysny commented 6 months ago

Most probably a duplicate of #14091