Skip to content

Commit e2188b2

Browse files
Fail client result if client can't parse invocation argument(s) (#47003)
Co-authored-by: Brennan Conroy <[email protected]>
1 parent 7124b90 commit e2188b2

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,11 @@ private async Task SendWithLock(ConnectionState expectedConnectionState, HubMess
986986
// The server can't receive a response, so we just drop the message and log
987987
// REVIEW: Is this the right approach?
988988
Log.ArgumentBindingFailure(_logger, bindingFailure.InvocationId, bindingFailure.Target, bindingFailure.BindingFailure.SourceException);
989+
990+
if (!string.IsNullOrEmpty(bindingFailure.InvocationId))
991+
{
992+
await SendWithLock(connectionState, CompletionMessage.WithError(bindingFailure.InvocationId, "Client failed to parse argument(s)."), cancellationToken: default).ConfigureAwait(false);
993+
}
989994
break;
990995
case InvocationMessage invocation:
991996
Log.ReceivedInvocation(_logger, invocation.InvocationId, invocation.Target, invocation.Arguments);

src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.Protocol.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,31 @@ public async Task ClientResultReturnsErrorIfNoResultFromClient()
852852
}
853853
}
854854

855+
[Fact]
856+
public async Task ClientResultReturnsErrorIfCannotParseArgument()
857+
{
858+
var connection = new TestConnection();
859+
var hubConnection = CreateHubConnection(connection);
860+
try
861+
{
862+
await hubConnection.StartAsync().DefaultTimeout();
863+
864+
// No result provided
865+
hubConnection.On("Result", (string _) => 1);
866+
867+
await connection.ReceiveTextAsync("{\"type\":1,\"invocationId\":\"1\",\"target\":\"Result\",\"arguments\":[15]}\u001e").DefaultTimeout();
868+
869+
var invokeMessage = await connection.ReadSentTextMessageAsync().DefaultTimeout();
870+
871+
Assert.Equal("{\"type\":3,\"invocationId\":\"1\",\"error\":\"Client failed to parse argument(s).\"}", invokeMessage);
872+
}
873+
finally
874+
{
875+
await hubConnection.DisposeAsync().DefaultTimeout();
876+
await connection.DisposeAsync().DefaultTimeout();
877+
}
878+
}
879+
855880
[Fact]
856881
public async Task ClientResultCanReturnNullResult()
857882
{

src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ private void ReceiveLoop(ByteBuffer payload)
469469
case INVOCATION_BINDING_FAILURE:
470470
InvocationBindingFailureMessage msg = (InvocationBindingFailureMessage)message;
471471
logger.error("Failed to bind arguments received in invocation '{}' of '{}'.", msg.getInvocationId(), msg.getTarget(), msg.getException());
472+
473+
if (msg.getInvocationId() != null) {
474+
sendHubMessageWithLock(new CompletionMessage(null, msg.getInvocationId(),
475+
null, "Client failed to parse argument(s)."));
476+
}
472477
break;
473478
case INVOCATION:
474479
InvocationMessage invocationMessage = (InvocationMessage) message;

src/SignalR/clients/java/signalr/test/src/main/java/com/microsoft/signalr/HubConnection.ReturnResultTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,4 +429,22 @@ public void clientResultHandlerDoesNotBlockOtherHandlers() {
429429
String expected = "{\"type\":3,\"invocationId\":\"1\",\"result\":\"bob\"}" + RECORD_SEPARATOR;
430430
assertEquals(expected, TestUtils.byteBufferToString(message));
431431
}
432+
433+
@Test
434+
public void clientResultReturnsErrorIfCannotParseArgument() {
435+
MockTransport mockTransport = new MockTransport();
436+
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);
437+
438+
hubConnection.onWithResult("inc", (i) -> {
439+
return Single.just("bob");
440+
}, Integer.class);
441+
442+
hubConnection.start().timeout(30, TimeUnit.SECONDS).blockingAwait();
443+
SingleSubject<ByteBuffer> sendTask = mockTransport.getNextSentMessage();
444+
mockTransport.receiveMessage("{\"type\":1,\"invocationId\":\"1\",\"target\":\"inc\",\"arguments\":[\"not int\"]}" + RECORD_SEPARATOR);
445+
446+
ByteBuffer message = sendTask.timeout(30, TimeUnit.SECONDS).blockingGet();
447+
String expected = "{\"type\":3,\"invocationId\":\"1\",\"error\":\"Client failed to parse argument(s).\"}" + RECORD_SEPARATOR;
448+
assertEquals(expected, TestUtils.byteBufferToString(message));
449+
}
432450
}

0 commit comments

Comments
 (0)