aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/Grpc.Core
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jtattermusch@google.com>2017-08-08 16:10:23 +0200
committerGravatar Jan Tattermusch <jtattermusch@google.com>2017-08-08 16:35:35 +0200
commite64825c302e1eacac43d2b21049fddaa25e11902 (patch)
tree1938ea677cf8a11aa32a7a5a787dfb204a106e8f /src/csharp/Grpc.Core
parent29945157f07a577bdc1b40ae2973dce30b65ab02 (diff)
Populate trailers in RpcException
Diffstat (limited to 'src/csharp/Grpc.Core')
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs8
-rw-r--r--src/csharp/Grpc.Core/RpcException.cs28
2 files changed, 32 insertions, 4 deletions
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 6e6ca7cd53..17109de587 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.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;
}
diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs
index 01b9e4fb1a..d2c912e73a 100644
--- a/src/csharp/Grpc.Core/RpcException.cs
+++ b/src/csharp/Grpc.Core/RpcException.cs
@@ -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;
+ }
+ }
}
}