-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Describe the bug
We are encountering a set of crashes from within the SignalR Java SDK. There are two separate issues but both are uncaught exceptions that currently crash our app. The two issues are:
- com.microsoft.signalr.HubConnection$ConnectionState.lambda$timeoutHandshakeResponse$0
java.util.concurrent.TimeoutException: Timed out waiting for the server to respond to the handshake message. - com.microsoft.signalr.HandshakeProtocol.parseHandshakeResponse
HandshakeProtocol.java, line 21
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
Note that the issue is not that the exception is being thrown in the first place, but that RxJava delivers it as an UndeliverableException and not through the subject as intended:
Lines 1433 to 1440 in bc1ff6a
| handshakeTimeout.schedule(() -> { | |
| // If onError is called on a completed subject the global error handler is called | |
| if (!(handshakeResponseSubject.hasComplete() || handshakeResponseSubject.hasThrowable())) | |
| { | |
| handshakeResponseSubject.onError( | |
| new TimeoutException("Timed out waiting for the server to respond to the handshake message.")); | |
| } | |
| }, timeout, unit); |
I am wondering if there could be a race between the timeout and handleHandshake that could lead to the Subject being completed multiple times since there is no synchronization in place.
I'm also curious why the timeout is handled by creating a new executor instead of just using RxJava's timeout operator?
For the time being we are registering an RxJava error handler to log and swallow these exceptions but it would be good if this could be fixed and the errors are being propagated to the Completable that is returned by HubConnection.start()
To Reproduce
Wasn't able to reproduce this.
Exceptions (if any)
Stacktrace TimeoutException:
io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | java.util.concurrent.TimeoutException: Timed out waiting for the server to respond to the handshake message.
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
at io.reactivex.subjects.CompletableSubject.onError(CompletableSubject.java:131)
at com.microsoft.signalr.HubConnection$ConnectionState.lambda$timeoutHandshakeResponse$0(HubConnection.java:1428)
at com.microsoft.signalr.HubConnection$ConnectionState.lambda$timeoutHandshakeResponse$0$HubConnection$ConnectionState(HubConnection.java)
at com.microsoft.signalr.-$$Lambda$HubConnection$ConnectionState$_fs5XriBgCmY7mCMawuT2CL0Nx4.run(-.java)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:459)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.util.concurrent.TimeoutException: Timed out waiting for the server to respond to the handshake message.
at com.microsoft.signalr.HubConnection$ConnectionState.lambda$timeoutHandshakeResponse$0(HubConnection.java:1428)
at com.microsoft.signalr.HubConnection$ConnectionState.lambda$timeoutHandshakeResponse$0$HubConnection$ConnectionState(HubConnection.java)
at com.microsoft.signalr.-$$Lambda$HubConnection$ConnectionState$_fs5XriBgCmY7mCMawuT2CL0Nx4.run(-.java)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:459)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Stacktrace TimeoutException:
io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | java.lang.RuntimeException: An invalid handshake response was received from the server.
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
at io.reactivex.subjects.CompletableSubject.onError(CompletableSubject.java:131)
at com.microsoft.signalr.HubConnection$ConnectionState.handleHandshake(HubConnection.java:1407)
at com.microsoft.signalr.HubConnection.ReceiveLoop(HubConnection.java:437)
at com.microsoft.signalr.HubConnection.lambda$new$0(HubConnection.java:162)
at com.microsoft.signalr.HubConnection.lambda$new$0$HubConnection(HubConnection.java)
at com.microsoft.signalr.-$$Lambda$HubConnection$QTbpx7gje_2sI4dX1CsfAa9dG7g.invoke(-.java:2)
at com.microsoft.signalr.WebSocketTransport.onReceive(WebSocketTransport.java:75)
at com.microsoft.signalr.WebSocketTransport.lambda$start$0(WebSocketTransport.java:52)
at com.microsoft.signalr.WebSocketTransport.lambda$start$0$WebSocketTransport(WebSocketTransport.java)
at com.microsoft.signalr.-$$Lambda$WebSocketTransport$IuEB82SnLNJc1Av0IiMi3-Bx-v8.invoke(-.java)
at com.microsoft.signalr.OkHttpWebSocketWrapper$SignalRWebSocketListener.onMessage(OkHttpWebSocketWrapper.java:100)
at okhttp3.internal.ws.RealWebSocket.onReadMessage(RealWebSocket.java:338)
at okhttp3.internal.ws.WebSocketReader.readMessageFrame(WebSocketReader.java:247)
at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.java:106)
at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.java:293)
at okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.java:195)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.java:519)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.RuntimeException: An invalid handshake response was received from the server.
at com.microsoft.signalr.HubConnection$ConnectionState.handleHandshake(HubConnection.java:1406)
at com.microsoft.signalr.HubConnection.ReceiveLoop(HubConnection.java:437)
at com.microsoft.signalr.HubConnection.lambda$new$0(HubConnection.java:162)
at com.microsoft.signalr.HubConnection.lambda$new$0$HubConnection(HubConnection.java)
at com.microsoft.signalr.-$$Lambda$HubConnection$QTbpx7gje_2sI4dX1CsfAa9dG7g.invoke(-.java:2)
at com.microsoft.signalr.WebSocketTransport.onReceive(WebSocketTransport.java:75)
at com.microsoft.signalr.WebSocketTransport.lambda$start$0(WebSocketTransport.java:52)
at com.microsoft.signalr.WebSocketTransport.lambda$start$0$WebSocketTransport(WebSocketTransport.java)
at com.microsoft.signalr.-$$Lambda$WebSocketTransport$IuEB82SnLNJc1Av0IiMi3-Bx-v8.invoke(-.java)
at com.microsoft.signalr.OkHttpWebSocketWrapper$SignalRWebSocketListener.onMessage(OkHttpWebSocketWrapper.java:100)
at okhttp3.internal.ws.RealWebSocket.onReadMessage(RealWebSocket.java:338)
at okhttp3.internal.ws.WebSocketReader.readMessageFrame(WebSocketReader.java:247)
at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.java:106)
at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.java:293)
at okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.java:195)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.java:519)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
at com.google.gson.Gson.fromJson(Gson.java:927)
at com.google.gson.Gson.fromJson(Gson.java:892)
at com.google.gson.Gson.fromJson(Gson.java:841)
at com.google.gson.Gson.fromJson(Gson.java:813)
at com.microsoft.signalr.HandshakeProtocol.parseHandshakeResponse(HandshakeProtocol.java:21)
at com.microsoft.signalr.HubConnection$ConnectionState.handleHandshake(HubConnection.java:1404)
at com.microsoft.signalr.HubConnection.ReceiveLoop(HubConnection.java:437)
at com.microsoft.signalr.HubConnection.lambda$new$0(HubConnection.java:162)
at com.microsoft.signalr.HubConnection.lambda$new$0$HubConnection(HubConnection.java)
at com.microsoft.signalr.-$$Lambda$HubConnection$QTbpx7gje_2sI4dX1CsfAa9dG7g.invoke(-.java:2)
at com.microsoft.signalr.WebSocketTransport.onReceive(WebSocketTransport.java:75)
at com.microsoft.signalr.WebSocketTransport.lambda$start$0(WebSocketTransport.java:52)
at com.microsoft.signalr.WebSocketTransport.lambda$start$0$WebSocketTransport(WebSocketTransport.java)
at com.microsoft.signalr.-$$Lambda$WebSocketTransport$IuEB82SnLNJc1Av0IiMi3-Bx-v8.invoke(-.java)
at com.microsoft.signalr.OkHttpWebSocketWrapper$SignalRWebSocketListener.onMessage(OkHttpWebSocketWrapper.java:100)
at okhttp3.internal.ws.RealWebSocket.onReadMessage(RealWebSocket.java:338)
at okhttp3.internal.ws.WebSocketReader.readMessageFrame(WebSocketReader.java:247)
at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.java:106)
at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.java:293)
at okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.java:195)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.java:519)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Further technical details
- SignalR Java SDK 5.0.3