From a550ae6cc3fec741c0fc9c8206ee6ff012c52ba3 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Wed, 8 Aug 2018 15:55:33 -0700 Subject: [PATCH] Provide a better error message when invoking a non-existant hub method (#2768) --- .../Internal/DefaultHubDispatcher.cs | 2 +- .../Protocol/MessagePackHubProtocol.cs | 4 +- .../HubConnectionTests.cs | 41 +++++++++++++++++-- .../HubConnectionHandlerTests.cs | 14 +++---- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs index 4f1fc15668..d26d10ac89 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs @@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal { if (!_methods.TryGetValue(methodName, out var descriptor)) { - return Type.EmptyTypes; + throw new HubException("Method does not exist."); } return descriptor.ParameterTypes; } diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs index 0b693605bf..d4e29baf92 100644 --- a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs @@ -157,10 +157,10 @@ namespace Microsoft.AspNetCore.SignalR.Protocol } var target = ReadString(input, ref offset, "target"); - var parameterTypes = binder.GetParameterTypes(target); try { + var parameterTypes = binder.GetParameterTypes(target); var arguments = BindArguments(input, ref offset, parameterTypes, resolver); return ApplyHeaders(headers, new InvocationMessage(invocationId, target, arguments)); } @@ -175,10 +175,10 @@ namespace Microsoft.AspNetCore.SignalR.Protocol var headers = ReadHeaders(input, ref offset); var invocationId = ReadInvocationId(input, ref offset); var target = ReadString(input, ref offset, "target"); - var parameterTypes = binder.GetParameterTypes(target); try { + var parameterTypes = binder.GetParameterTypes(target); var arguments = BindArguments(input, ref offset, parameterTypes, resolver); return ApplyHeaders(headers, new StreamInvocationMessage(invocationId, target, arguments)); } diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs index 313efa5b5c..0fe68b0589 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs @@ -464,7 +464,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests bool ExpectedErrors(WriteContext writeContext) { return writeContext.LoggerName == DefaultHubDispatcherLoggerName && - writeContext.EventId.Name == "UnknownHubMethod"; + writeContext.EventId.Name == "FailedInvokingHubMethod"; } var hubProtocol = HubProtocols[hubProtocolName]; @@ -476,7 +476,40 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests await connection.StartAsync().OrTimeout(); var ex = await Assert.ThrowsAsync(() => connection.InvokeAsync("!@#$%")).OrTimeout(); - Assert.Equal("Unknown hub method '!@#$%'", ex.Message); + Assert.Equal("Failed to invoke '!@#$%' due to an error on the server. HubException: Method does not exist.", ex.Message); + } + catch (Exception ex) + { + loggerFactory.CreateLogger().LogError(ex, "{ExceptionType} from test", ex.GetType().FullName); + throw; + } + finally + { + await connection.DisposeAsync().OrTimeout(); + } + } + } + + [Theory] + [MemberData(nameof(HubProtocolsAndTransportsAndHubPaths))] + public async Task ServerThrowsHubExceptionIfHubMethodCannotBeResolvedAndArgumentsPassedIn(string hubProtocolName, HttpTransportType transportType, string hubPath) + { + bool ExpectedErrors(WriteContext writeContext) + { + return writeContext.LoggerName == DefaultHubDispatcherLoggerName && + writeContext.EventId.Name == "FailedInvokingHubMethod"; + } + + var hubProtocol = HubProtocols[hubProtocolName]; + using (StartVerifiableLog(out var loggerFactory, $"{nameof(ServerThrowsHubExceptionIfHubMethodCannotBeResolvedAndArgumentsPassedIn)}_{hubProtocol.Name}_{transportType}_{hubPath.TrimStart('/')}", expectedErrorsFilter: ExpectedErrors)) + { + var connection = CreateHubConnection(hubPath, transportType, hubProtocol, loggerFactory); + try + { + await connection.StartAsync().OrTimeout(); + + var ex = await Assert.ThrowsAsync(() => connection.InvokeAsync("!@#$%", 10, "test")).OrTimeout(); + Assert.Equal("Failed to invoke '!@#$%' due to an error on the server. HubException: Method does not exist.", ex.Message); } catch (Exception ex) { @@ -563,7 +596,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests bool ExpectedErrors(WriteContext writeContext) { return writeContext.LoggerName == DefaultHubDispatcherLoggerName && - writeContext.EventId.Name == "UnknownHubMethod"; + writeContext.EventId.Name == "FailedInvokingHubMethod"; } var hubProtocol = HubProtocols[hubProtocolName]; @@ -576,7 +609,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests var channel = await connection.StreamAsChannelAsync("!@#$%"); var ex = await Assert.ThrowsAsync(() => channel.ReadAllAsync().OrTimeout()); - Assert.Equal("Unknown hub method '!@#$%'", ex.Message); + Assert.Equal("Failed to invoke '!@#$%' due to an error on the server. HubException: Method does not exist.", ex.Message); } catch (Exception ex) { diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs index 02a5146e02..c637f9e131 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs @@ -799,7 +799,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests var result = await client.InvokeAsync(nameof(MethodHub.OnDisconnectedAsync)).OrTimeout(); - Assert.Equal("Unknown hub method 'OnDisconnectedAsync'", result.Error); + Assert.Equal("Failed to invoke 'OnDisconnectedAsync' due to an error on the server. HubException: Method does not exist.", result.Error); // kill the connection client.Dispose(); @@ -837,7 +837,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests var result = await client.InvokeAsync(nameof(MethodHub.StaticMethod)).OrTimeout(); - Assert.Equal("Unknown hub method 'StaticMethod'", result.Error); + Assert.Equal("Failed to invoke 'StaticMethod' due to an error on the server. HubException: Method does not exist.", result.Error); // kill the connection client.Dispose(); @@ -858,16 +858,16 @@ namespace Microsoft.AspNetCore.SignalR.Tests var connectionHandlerTask = await client.ConnectAsync(connectionHandler); var result = await client.InvokeAsync(nameof(MethodHub.ToString)).OrTimeout(); - Assert.Equal("Unknown hub method 'ToString'", result.Error); + Assert.Equal("Failed to invoke 'ToString' due to an error on the server. HubException: Method does not exist.", result.Error); result = await client.InvokeAsync(nameof(MethodHub.GetHashCode)).OrTimeout(); - Assert.Equal("Unknown hub method 'GetHashCode'", result.Error); + Assert.Equal("Failed to invoke 'GetHashCode' due to an error on the server. HubException: Method does not exist.", result.Error); result = await client.InvokeAsync(nameof(MethodHub.Equals)).OrTimeout(); - Assert.Equal("Unknown hub method 'Equals'", result.Error); + Assert.Equal("Failed to invoke 'Equals' due to an error on the server. HubException: Method does not exist.", result.Error); result = await client.InvokeAsync(nameof(MethodHub.ReferenceEquals)).OrTimeout(); - Assert.Equal("Unknown hub method 'ReferenceEquals'", result.Error); + Assert.Equal("Failed to invoke 'ReferenceEquals' due to an error on the server. HubException: Method does not exist.", result.Error); // kill the connection client.Dispose(); @@ -889,7 +889,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests var result = await client.InvokeAsync(nameof(MethodHub.Dispose)).OrTimeout(); - Assert.Equal("Unknown hub method 'Dispose'", result.Error); + Assert.Equal("Failed to invoke 'Dispose' due to an error on the server. HubException: Method does not exist.", result.Error); // kill the connection client.Dispose();