Populate trailers in RpcException

pull/12120/head
Jan Tattermusch 7 years ago
parent 29945157f0
commit e64825c302
  1. 8
      src/csharp/Grpc.Core/Internal/AsyncCall.cs
  2. 28
      src/csharp/Grpc.Core/RpcException.cs

@ -329,7 +329,7 @@ namespace Grpc.Core.Internal
protected override Exception GetRpcExceptionClientOnly()
{
return new RpcException(finishedStatus.Value.Status);
return new RpcException(finishedStatus.Value.Status, finishedStatus.Value.Trailers);
}
protected override Task CheckSendAllowedOrEarlyResult()
@ -348,7 +348,7 @@ namespace Grpc.Core.Internal
// Writing after the call has finished is not a programming error because server can close
// the call anytime, so don't throw directly, but let the write task finish with an error.
var tcs = new TaskCompletionSource<object>();
tcs.SetException(new RpcException(finishedStatus.Value.Status));
tcs.SetException(new RpcException(finishedStatus.Value.Status, finishedStatus.Value.Trailers));
return tcs.Task;
}
@ -468,7 +468,7 @@ namespace Grpc.Core.Internal
var status = receivedStatus.Status;
if (status.StatusCode != StatusCode.OK)
{
unaryResponseTcs.SetException(new RpcException(status));
unaryResponseTcs.SetException(new RpcException(status, receivedStatus.Trailers));
return;
}
@ -506,7 +506,7 @@ namespace Grpc.Core.Internal
var status = receivedStatus.Status;
if (status.StatusCode != StatusCode.OK)
{
streamingResponseCallFinishedTcs.SetException(new RpcException(status));
streamingResponseCallFinishedTcs.SetException(new RpcException(status, receivedStatus.Trailers));
return;
}

@ -17,6 +17,7 @@
#endregion
using System;
using Grpc.Core.Utils;
namespace Grpc.Core
{
@ -26,6 +27,7 @@ namespace Grpc.Core
public class RpcException : Exception
{
private readonly Status status;
private readonly Metadata trailers;
/// <summary>
/// Creates a new <c>RpcException</c> associated with given status.
@ -34,6 +36,7 @@ namespace Grpc.Core
public RpcException(Status status) : base(status.ToString())
{
this.status = status;
this.trailers = Metadata.Empty;
}
/// <summary>
@ -44,6 +47,18 @@ namespace Grpc.Core
public RpcException(Status status, string message) : base(message)
{
this.status = status;
this.trailers = Metadata.Empty;
}
/// <summary>
/// Creates a new <c>RpcException</c> associated with given status and trailing response metadata.
/// </summary>
/// <param name="status">Resulting status of a call.</param>
/// <param name="trailers">Response trailing metadata.</param>
public RpcException(Status status, Metadata trailers) : base(status.ToString())
{
this.status = status;
this.trailers = GrpcPreconditions.CheckNotNull(trailers);
}
/// <summary>
@ -56,5 +71,18 @@ namespace Grpc.Core
return status;
}
}
/// <summary>
/// Gets the call trailing metadata.
/// Trailers only have meaningful content for client-side calls (in which case they represent the trailing metadata sent by the server when closing the call).
/// Instances of <c>RpcException</c> thrown by the server-side part of the stack will have trailers always set to empty.
/// </summary>
public Metadata Trailers
{
get
{
return trailers;
}
}
}
}

Loading…
Cancel
Save