Skip to content
Snippets Groups Projects
Commit e64825c3 authored by Jan Tattermusch's avatar Jan Tattermusch
Browse files

Populate trailers in RpcException

parent 29945157
No related branches found
No related tags found
No related merge requests found
...@@ -329,7 +329,7 @@ namespace Grpc.Core.Internal ...@@ -329,7 +329,7 @@ namespace Grpc.Core.Internal
protected override Exception GetRpcExceptionClientOnly() protected override Exception GetRpcExceptionClientOnly()
{ {
return new RpcException(finishedStatus.Value.Status); return new RpcException(finishedStatus.Value.Status, finishedStatus.Value.Trailers);
} }
protected override Task CheckSendAllowedOrEarlyResult() protected override Task CheckSendAllowedOrEarlyResult()
...@@ -348,7 +348,7 @@ namespace Grpc.Core.Internal ...@@ -348,7 +348,7 @@ namespace Grpc.Core.Internal
// Writing after the call has finished is not a programming error because server can close // 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. // the call anytime, so don't throw directly, but let the write task finish with an error.
var tcs = new TaskCompletionSource<object>(); 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; return tcs.Task;
} }
...@@ -468,7 +468,7 @@ namespace Grpc.Core.Internal ...@@ -468,7 +468,7 @@ namespace Grpc.Core.Internal
var status = receivedStatus.Status; var status = receivedStatus.Status;
if (status.StatusCode != StatusCode.OK) if (status.StatusCode != StatusCode.OK)
{ {
unaryResponseTcs.SetException(new RpcException(status)); unaryResponseTcs.SetException(new RpcException(status, receivedStatus.Trailers));
return; return;
} }
...@@ -506,7 +506,7 @@ namespace Grpc.Core.Internal ...@@ -506,7 +506,7 @@ namespace Grpc.Core.Internal
var status = receivedStatus.Status; var status = receivedStatus.Status;
if (status.StatusCode != StatusCode.OK) if (status.StatusCode != StatusCode.OK)
{ {
streamingResponseCallFinishedTcs.SetException(new RpcException(status)); streamingResponseCallFinishedTcs.SetException(new RpcException(status, receivedStatus.Trailers));
return; return;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#endregion #endregion
using System; using System;
using Grpc.Core.Utils;
namespace Grpc.Core namespace Grpc.Core
{ {
...@@ -26,6 +27,7 @@ namespace Grpc.Core ...@@ -26,6 +27,7 @@ namespace Grpc.Core
public class RpcException : Exception public class RpcException : Exception
{ {
private readonly Status status; private readonly Status status;
private readonly Metadata trailers;
/// <summary> /// <summary>
/// Creates a new <c>RpcException</c> associated with given status. /// Creates a new <c>RpcException</c> associated with given status.
...@@ -34,6 +36,7 @@ namespace Grpc.Core ...@@ -34,6 +36,7 @@ namespace Grpc.Core
public RpcException(Status status) : base(status.ToString()) public RpcException(Status status) : base(status.ToString())
{ {
this.status = status; this.status = status;
this.trailers = Metadata.Empty;
} }
/// <summary> /// <summary>
...@@ -44,6 +47,18 @@ namespace Grpc.Core ...@@ -44,6 +47,18 @@ namespace Grpc.Core
public RpcException(Status status, string message) : base(message) public RpcException(Status status, string message) : base(message)
{ {
this.status = status; 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> /// <summary>
...@@ -56,5 +71,18 @@ namespace Grpc.Core ...@@ -56,5 +71,18 @@ namespace Grpc.Core
return status; 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;
}
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment