Skip to content

Commit

Permalink
Merge pull request #749 from Cysharp/feature/DiagnosticHandlerException
Browse files Browse the repository at this point in the history
Add Exception argument to Handler
  • Loading branch information
mayuki authored Mar 21, 2024
2 parents ef6f04a + fdf1fd2 commit cf5e50a
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,34 @@ static void EmitHelperMethods(StreamingHubClientBuildContext ctx)
{
var requestId = global::System.Guid.NewGuid();
diagnosticHandler?.OnRequestBegin(this, requestId, callerMemberName, message, isFireAndForget: false);
var result = await base.WriteMessageWithResponseAsync<TRequest, TResponse>(methodId, message).ConfigureAwait(false);
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, result);
return result;
try
{
var result = await base.WriteMessageWithResponseAsync<TRequest, TResponse>(methodId, message).ConfigureAwait(false);
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, result, default);
return result;
}
catch (global::System.Exception e)
{
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, default(TResponse), e);
throw;
}
}
async global::System.Threading.Tasks.Task<TResponse> WriteMessageFireAndForgetDiagnosticAsync<TRequest, TResponse>(int methodId, TRequest message, [global::System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = default!)
{
var requestId = global::System.Guid.NewGuid();
diagnosticHandler?.OnRequestBegin(this, requestId, callerMemberName, message, isFireAndForget: true);
var result = await base.WriteMessageFireAndForgetAsync<TRequest, TResponse>(methodId, message).ConfigureAwait(false);
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, result);
return result;
try
{
var result = await base.WriteMessageFireAndForgetAsync<TRequest, TResponse>(methodId, message).ConfigureAwait(false);
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, result, default);
return result;
}
catch (global::System.Exception e)
{
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, default(TResponse), e);
throw;
}
}
""");
ctx.Writer.AppendLine();
Expand Down Expand Up @@ -177,7 +193,7 @@ class FireAndForgetClient : {{ctx.Hub.ServiceType.FullName}}
public FireAndForgetClient({{ctx.Hub.GetClientFullName()}} parent)
=> this.parent = parent;
public {{ctx.Hub.ServiceType.FullName}} FireAndForget() => this;
public global::System.Threading.Tasks.Task DisposeAsync() => throw new global::System.NotSupportedException();
public global::System.Threading.Tasks.Task WaitForDisconnect() => throw new global::System.NotSupportedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public interface IStreamingHubDiagnosticHandler
/// <param name="requestId"></param>
/// <param name="methodName"></param>
/// <param name="response"></param>
void OnRequestEnd<THub, TResponse>(THub hubInstance, Guid requestId, string methodName, TResponse response);
/// <param name="exception"></param>
void OnRequestEnd<THub, TResponse>(THub hubInstance, Guid requestId, string methodName, TResponse response, Exception? exception);

/// <summary>
/// [Preview] The callback method when a method of HubReceiver is invoked. This API may change in the future.
Expand Down
3 changes: 2 additions & 1 deletion src/MagicOnion.Client/IStreamingHubDiagnosticHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public interface IStreamingHubDiagnosticHandler
/// <param name="requestId"></param>
/// <param name="methodName"></param>
/// <param name="response"></param>
void OnRequestEnd<THub, TResponse>(THub hubInstance, Guid requestId, string methodName, TResponse response);
/// <param name="exception"></param>
void OnRequestEnd<THub, TResponse>(THub hubInstance, Guid requestId, string methodName, TResponse response, Exception? exception);

/// <summary>
/// [Preview] The callback method when a method of HubReceiver is invoked. This API may change in the future.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,34 @@ public TempProject_MyHubClient(global::Grpc.Core.CallInvoker callInvoker, global
{
var requestId = global::System.Guid.NewGuid();
diagnosticHandler?.OnRequestBegin(this, requestId, callerMemberName, message, isFireAndForget: false);
var result = await base.WriteMessageWithResponseAsync<TRequest, TResponse>(methodId, message).ConfigureAwait(false);
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, result);
return result;
try
{
var result = await base.WriteMessageWithResponseAsync<TRequest, TResponse>(methodId, message).ConfigureAwait(false);
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, result, default);
return result;
}
catch (global::System.Exception e)
{
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, default(TResponse), e);
throw;
}
}

async global::System.Threading.Tasks.Task<TResponse> WriteMessageFireAndForgetDiagnosticAsync<TRequest, TResponse>(int methodId, TRequest message, [global::System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = default!)
{
var requestId = global::System.Guid.NewGuid();
diagnosticHandler?.OnRequestBegin(this, requestId, callerMemberName, message, isFireAndForget: true);
var result = await base.WriteMessageFireAndForgetAsync<TRequest, TResponse>(methodId, message).ConfigureAwait(false);
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, result);
return result;
try
{
var result = await base.WriteMessageFireAndForgetAsync<TRequest, TResponse>(methodId, message).ConfigureAwait(false);
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, result, default);
return result;
}
catch (global::System.Exception e)
{
diagnosticHandler?.OnRequestEnd(this, requestId, callerMemberName, default(TResponse), e);
throw;
}
}

public global::System.Threading.Tasks.Task MethodA()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,38 @@ public async Task Request_Response_Void()
Assert.Equal(Nil.Default, endEvent.Response);
}

[Fact]
public async Task Request_Throw()
{
// Arrange
var httpClient = factory.CreateDefaultClient();
var channel = GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient });
var diagnosticHandler = new DiagnosticHandler();

MagicOnionGeneratedClientInitializerStreamingHubDiagnosticHandler.StreamingHubDiagnosticHandler = diagnosticHandler;

var receiver = Substitute.For<IStreamingHubTestHubReceiver>();
var client = await StreamingHubClient.ConnectAsync<IStreamingHubTestHub, IStreamingHubTestHubReceiver>(
channel, receiver,
factoryProvider: MagicOnionGeneratedClientInitializerStreamingHubDiagnosticHandler.StreamingHubClientFactoryProvider);

// Act
var ex = await Record.ExceptionAsync(async () => await client.Throw());

// Assert
Assert.Equal([DiagnosticHandler.EventType.OnRequestBegin, DiagnosticHandler.EventType.OnRequestEnd], diagnosticHandler.Events.Select(x => x.EventType));

var beginEvent = diagnosticHandler.Events.Single(x => x.EventType == DiagnosticHandler.EventType.OnRequestBegin);
var endEvent = diagnosticHandler.Events.Single(x => x.EventType == DiagnosticHandler.EventType.OnRequestEnd);

Assert.Equal(nameof(IStreamingHubTestHub.Throw), beginEvent.MethodName);
Assert.Equal(nameof(IStreamingHubTestHub.Throw), endEvent.MethodName);
Assert.Equal(beginEvent.RequestId, endEvent.RequestId);
Assert.Equal(Nil.Default, beginEvent.Request);
Assert.Equal(Nil.Default, endEvent.Response);
Assert.Equal(ex, endEvent.Exception);
}

[Fact]
public async Task Receiver()
{
Expand Down Expand Up @@ -153,21 +185,21 @@ public enum EventType
OnBroadcastEvent,
}

public List<(EventType EventType, object HubInstance, Guid RequestId, string MethodName, object? Request, object? Response)> Events { get; } = new ();
public List<(EventType EventType, object HubInstance, Guid RequestId, string MethodName, object? Request, object? Response, Exception? Exception)> Events { get; } = new ();

public void OnRequestBegin<THub, TRequest>(THub hubInstance, Guid requestId, string methodName, TRequest request, bool isFireAndForget)
{
Events.Add((EventType.OnRequestBegin, hubInstance!, requestId, methodName, request, default));
Events.Add((EventType.OnRequestBegin, hubInstance!, requestId, methodName, request, default, default));
}

public void OnRequestEnd<THub, TResponse>(THub hubInstance, Guid requestId, string methodName, TResponse response)
public void OnRequestEnd<THub, TResponse>(THub hubInstance, Guid requestId, string methodName, TResponse response, Exception? exception)
{
Events.Add((EventType.OnRequestEnd, hubInstance!, requestId, methodName, default, response));
Events.Add((EventType.OnRequestEnd, hubInstance!, requestId, methodName, default, response, exception));
}

public void OnBroadcastEvent<THub, T>(THub hubInstance, string methodName, T value)
{
Events.Add((EventType.OnBroadcastEvent, hubInstance!, Guid.Empty, methodName, default, value));
Events.Add((EventType.OnBroadcastEvent, hubInstance!, Guid.Empty, methodName, default, value, default));
}
}
}
Expand Down

0 comments on commit cf5e50a

Please sign in to comment.