Skip to content

Commit

Permalink
Fail client result if client can't parse invocation argument(s) (#47003)
Browse files Browse the repository at this point in the history
Co-authored-by: Brennan Conroy <brecon@microsoft.com>
  • Loading branch information
github-actions[bot] and BrennanConroy authored Mar 10, 2023
1 parent 7124b90 commit e2188b2
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,11 @@ private async Task SendWithLock(ConnectionState expectedConnectionState, HubMess
// The server can't receive a response, so we just drop the message and log
// REVIEW: Is this the right approach?
Log.ArgumentBindingFailure(_logger, bindingFailure.InvocationId, bindingFailure.Target, bindingFailure.BindingFailure.SourceException);

if (!string.IsNullOrEmpty(bindingFailure.InvocationId))
{
await SendWithLock(connectionState, CompletionMessage.WithError(bindingFailure.InvocationId, "Client failed to parse argument(s)."), cancellationToken: default).ConfigureAwait(false);
}
break;
case InvocationMessage invocation:
Log.ReceivedInvocation(_logger, invocation.InvocationId, invocation.Target, invocation.Arguments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,31 @@ public async Task ClientResultReturnsErrorIfNoResultFromClient()
}
}

[Fact]
public async Task ClientResultReturnsErrorIfCannotParseArgument()
{
var connection = new TestConnection();
var hubConnection = CreateHubConnection(connection);
try
{
await hubConnection.StartAsync().DefaultTimeout();

// No result provided
hubConnection.On("Result", (string _) => 1);

await connection.ReceiveTextAsync("{\"type\":1,\"invocationId\":\"1\",\"target\":\"Result\",\"arguments\":[15]}\u001e").DefaultTimeout();

var invokeMessage = await connection.ReadSentTextMessageAsync().DefaultTimeout();

Assert.Equal("{\"type\":3,\"invocationId\":\"1\",\"error\":\"Client failed to parse argument(s).\"}", invokeMessage);
}
finally
{
await hubConnection.DisposeAsync().DefaultTimeout();
await connection.DisposeAsync().DefaultTimeout();
}
}

[Fact]
public async Task ClientResultCanReturnNullResult()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,11 @@ private void ReceiveLoop(ByteBuffer payload)
case INVOCATION_BINDING_FAILURE:
InvocationBindingFailureMessage msg = (InvocationBindingFailureMessage)message;
logger.error("Failed to bind arguments received in invocation '{}' of '{}'.", msg.getInvocationId(), msg.getTarget(), msg.getException());

if (msg.getInvocationId() != null) {
sendHubMessageWithLock(new CompletionMessage(null, msg.getInvocationId(),
null, "Client failed to parse argument(s)."));
}
break;
case INVOCATION:
InvocationMessage invocationMessage = (InvocationMessage) message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,4 +429,22 @@ public void clientResultHandlerDoesNotBlockOtherHandlers() {
String expected = "{\"type\":3,\"invocationId\":\"1\",\"result\":\"bob\"}" + RECORD_SEPARATOR;
assertEquals(expected, TestUtils.byteBufferToString(message));
}

@Test
public void clientResultReturnsErrorIfCannotParseArgument() {
MockTransport mockTransport = new MockTransport();
HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport);

hubConnection.onWithResult("inc", (i) -> {
return Single.just("bob");
}, Integer.class);

hubConnection.start().timeout(30, TimeUnit.SECONDS).blockingAwait();
SingleSubject<ByteBuffer> sendTask = mockTransport.getNextSentMessage();
mockTransport.receiveMessage("{\"type\":1,\"invocationId\":\"1\",\"target\":\"inc\",\"arguments\":[\"not int\"]}" + RECORD_SEPARATOR);

ByteBuffer message = sendTask.timeout(30, TimeUnit.SECONDS).blockingGet();
String expected = "{\"type\":3,\"invocationId\":\"1\",\"error\":\"Client failed to parse argument(s).\"}" + RECORD_SEPARATOR;
assertEquals(expected, TestUtils.byteBufferToString(message));
}
}

0 comments on commit e2188b2

Please sign in to comment.