flow: Confirmed duplicate message from the client if a Throwable is thrown

Example

@Route("")
@Theme(Lumo.class)
public class DemoView extends VerticalLayout {

    public DemoView() {
        getElement().addEventListener("click", e -> {
            throw new Error("Fail");
        });
}

Clicking on the button logs two exceptions

[WARNING] Error for /
java.lang.Error: Fail
	at DemoView.lambda$0(DemoView.java:14)
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$0(ElementListenerMap.java:171)
	at java.util.ArrayList.forEach(ArrayList.java:1249)
	at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:171)
	at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:58)
	at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:60)
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:377)
	at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$0(ServerRpcHandler.java:367)
	at java.util.ArrayList.forEach(ArrayList.java:1249)
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:367)
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:309)
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89)
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1541)
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:345)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

which is expected but then the client side gets a 500 back. The client side then tries to re-send the message as it does not know if the message ever reached the server. This will cause another exception to be logged

[qtp1532675992-33] ERROR com.vaadin.flow.server.DefaultErrorHandler - 
java.lang.UnsupportedOperationException: Confirmed duplicate message from the client. Expected sync id: 1, got 0. Message start: {"csrfToken":"ab0f5d03-ba71-408a-8e60-9bfc09b8df65","rpc":[{"type":"event","node":3,"event":"click"}],"syncId":0,"clientId":0}
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:302)
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89)
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1541)
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:345)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:835)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1685)
	at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:225)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668)

In FW8, this case is handled as

            ui.getSession().getCommunicationManager().repaintAll(ui);

            if (rpcRequest.getClientToServerId() < expectedId) {
                // Just a duplicate message due to a bad connection or similar
                // It has already been handled by the server so it is safe to
                // ignore
                getLogger()
                        .fine("Ignoring old message from the client. Expected: "
                                + expectedId + ", got: "
                                + rpcRequest.getClientToServerId());

which seems more appropriate.

In real world, this happened during development when part of the code was not redeployed and caused a java.lang.NoSuchMethodError to be thrown

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 19 (5 by maintainers)

Commits related to this issue

Most upvoted comments

do we have any updated on this issue? I am facing same issue for vaadin 10.

I can confirm this bug is still existing in Vaadin 14.1.4. I would suggest to raise priority again!

java.lang.UnsupportedOperationException: Unexpected message id from the client. Expected sync id: 0, got 1. Message start: {“csrfToken”:“9608a964-6750-4a12-b241-e76d1dad2ad8”,“rpc”:[{“type”:“publishedEventHandler”,“node”:9,“templateEventMethodName”:“updateSelectedTab”,“templateEventMethodArgs”:[true]}],“syncId”:-1,“clientId”:1}

I’m seeing a similar error. Vaadin 14.

Please do not use Error in your Java code. Errors are special JVM exceptions which indicate serious JVM problem, such as OutOfMemoryError. When an Error is thrown, it is not expected for JVM to be able to continue; e.g. catching OutOfMemoryError and doing something about it will most likely cause another OutOfMemoryError to be thrown.

Quoting Error javadoc:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.

Instead of Errors, use RuntimeException.

Therefore, I’d perhaps propose to not give Errors any special treatment.

Getting “confirmed duplicate message” almost daily. Currently on 13.0.4.

2019-04-23 18:18:33.098  WARN 18342 --- [nio-8080-exec-6] c.v.f.s.c.r.AbstractRpcInvocationHandler : Got an RPC for non-existent node: 447
2019-04-23 18:18:33.139 ERROR 18342 --- [nio-8080-exec-3] c.v.flow.server.DefaultErrorHandler      : 

java.lang.UnsupportedOperationException: Confirmed duplicate message from the client. Expected sync id: 23, got 22. Message start: {"csrfToken":"793e0f18-f890-4fb5-9e13-17a9438efe75","rpc":[{"type":"publishedEventHandler","node":447,"templateEventMethodName":"select","templateEventMethodArgs":["4"]},{"type":"publishedEventHandler","node":447,"templateEventMethodName":"setDetailsVisible","templateEventMethodArgs":["4"]}],"syncId":22,"clientId":22}
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:303) ~[flow-server-1.4.3.jar:1.4.3]
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89) ~[flow-server-1.4.3.jar:1.4.3]
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-1.4.3.jar:1.4.3]
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1507) ~[flow-server-1.4.3.jar:1.4.3]
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:242) [flow-server-1.4.3.jar:1.4.3]
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:81) [vaadin-spring-11.0.0.jar:na]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.31.jar:8.5.31]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728) [tomcat-embed-core-8.5.31.jar:8.5.31]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:470) [tomcat-embed-core-8.5.31.jar:8.5.31]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:356) [tomcat-embed-core-8.5.31.jar:8.5.31]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316) [tomcat-embed-core-8.5.31.jar:8.5.31]
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]