Pass serialization exceptions to Hub disconnect (#24408)

This commit is contained in:
Brennan 2020-07-31 10:13:28 -07:00 committed by GitHub
parent f28ef7c3e8
commit 4290bcc782
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 13 deletions

View File

@ -91,6 +91,8 @@ namespace Microsoft.AspNetCore.SignalR
internal HubCallerContext HubCallerContext { get; }
internal Exception CloseException { get; private set; }
/// <summary>
/// Gets a <see cref="CancellationToken"/> that notifies when the connection is aborted.
/// </summary>
@ -212,6 +214,7 @@ namespace Microsoft.AspNetCore.SignalR
}
catch (Exception ex)
{
CloseException = ex;
Log.FailedWritingMessage(_logger, ex);
AbortAllowReconnect();
@ -231,6 +234,7 @@ namespace Microsoft.AspNetCore.SignalR
}
catch (Exception ex)
{
CloseException = ex;
Log.FailedWritingMessage(_logger, ex);
AbortAllowReconnect();
@ -247,6 +251,7 @@ namespace Microsoft.AspNetCore.SignalR
}
catch (Exception ex)
{
CloseException = ex;
Log.FailedWritingMessage(_logger, ex);
AbortAllowReconnect();
@ -274,6 +279,7 @@ namespace Microsoft.AspNetCore.SignalR
}
catch (Exception ex)
{
CloseException = ex;
Log.FailedWritingMessage(_logger, ex);
AbortAllowReconnect();
}
@ -299,6 +305,7 @@ namespace Microsoft.AspNetCore.SignalR
}
catch (Exception ex)
{
CloseException = ex;
Log.FailedWritingMessage(_logger, ex);
AbortAllowReconnect();
}
@ -336,6 +343,7 @@ namespace Microsoft.AspNetCore.SignalR
}
catch (Exception ex)
{
CloseException = ex;
Log.FailedWritingMessage(_logger, ex);
AbortAllowReconnect();
}

View File

@ -182,7 +182,7 @@ namespace Microsoft.AspNetCore.SignalR
return;
}
await HubOnDisconnectedAsync(connection, null);
await HubOnDisconnectedAsync(connection, connection.CloseException);
}
private async Task HubOnDisconnectedAsync(HubConnectionContext connection, Exception exception)

View File

@ -189,16 +189,6 @@ namespace Microsoft.AspNetCore.SignalR.Tests
{
}
private class SelfRef
{
public SelfRef()
{
Self = this;
}
public SelfRef Self { get; set; }
}
public async Task<string> StreamingConcat(ChannelReader<string> source)
{
var sb = new StringBuilder();
@ -331,6 +321,16 @@ namespace Microsoft.AspNetCore.SignalR.Tests
}
}
internal class SelfRef
{
public SelfRef()
{
Self = this;
}
public SelfRef Self { get; set; }
}
public abstract class TestHub : Hub
{
public override Task OnConnectedAsync()
@ -1123,9 +1123,20 @@ namespace Microsoft.AspNetCore.SignalR.Tests
return base.OnConnectedAsync();
}
public Task ProtocolErrorSelf()
{
return Clients.Caller.SendAsync("Send", new SelfRef());
}
public Task ProtocolErrorAll()
{
return Clients.All.SendAsync("Send", new SelfRef());
}
public override Task OnDisconnectedAsync(Exception exception)
{
_state.TokenStateInDisconnected = Context.ConnectionAborted.IsCancellationRequested;
_state.DisconnectedException = exception;
return base.OnDisconnectedAsync(exception);
}
@ -1138,6 +1149,8 @@ namespace Microsoft.AspNetCore.SignalR.Tests
public bool TokenStateInConnected { get; set; }
public bool TokenStateInDisconnected { get; set; }
public Exception DisconnectedException { get; set; }
}
public class CallerServiceHub : Hub

View File

@ -19,10 +19,8 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Connections.Features;
using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.SignalR.Internal;
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
@ -3342,6 +3340,52 @@ namespace Microsoft.AspNetCore.SignalR.Tests
}
}
[Fact]
public async Task SerializationExceptionsSendSelfArePassedToOnDisconnectedAsync()
{
using (StartVerifiableLog(write => write.EventId.Name == "FailedWritingMessage"))
{
var state = new ConnectionLifetimeState();
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(s => s.AddSingleton(state), LoggerFactory);
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<ConnectionLifetimeHub>>();
using (var client = new TestClient())
{
var connectionHandlerTask = await client.ConnectAsync(connectionHandler);
// Test HubConnectionContext.WriteCore(HubMessage) codepath
await client.SendInvocationAsync(nameof(ConnectionLifetimeHub.ProtocolErrorSelf)).OrTimeout();
await connectionHandlerTask.OrTimeout();
Assert.IsType<System.Text.Json.JsonException>(state.DisconnectedException);
}
}
}
[Fact]
public async Task SerializationExceptionsSendAllArePassedToOnDisconnectedAsync()
{
using (StartVerifiableLog(write => write.EventId.Name == "FailedWritingMessage"))
{
var state = new ConnectionLifetimeState();
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(s => s.AddSingleton(state), LoggerFactory);
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<ConnectionLifetimeHub>>();
using (var client = new TestClient())
{
var connectionHandlerTask = await client.ConnectAsync(connectionHandler);
// Test HubConnectionContext.WriteCore(SerializedHubMessage) codepath
await client.SendInvocationAsync(nameof(ConnectionLifetimeHub.ProtocolErrorAll)).OrTimeout();
await connectionHandlerTask.OrTimeout();
Assert.IsType<System.Text.Json.JsonException>(state.DisconnectedException);
}
}
}
[Fact(Skip = "Magic auto cast not supported")]
public async Task UploadStreamItemInvalidTypeAutoCasts()
{