diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs index 78c7f3ad5bb..49ec2636db6 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs @@ -78,7 +78,7 @@ namespace Grpc.Core.Internal.Tests { var resultTask = asyncCall.UnaryCallAsync("request1"); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, - new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null), CreateResponsePayload(), new Metadata()); @@ -102,7 +102,7 @@ namespace Grpc.Core.Internal.Tests { var resultTask = asyncCall.UnaryCallAsync("request1"); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, - new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null), null, new Metadata()); @@ -159,7 +159,7 @@ namespace Grpc.Core.Internal.Tests { var resultTask = asyncCall.ClientStreamingCallAsync(); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, - new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null), CreateResponsePayload(), new Metadata()); @@ -197,7 +197,7 @@ namespace Grpc.Core.Internal.Tests completeTask.Wait(); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, - new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null), CreateResponsePayload(), new Metadata()); @@ -283,7 +283,7 @@ namespace Grpc.Core.Internal.Tests var requestStream = new ClientRequestStream(asyncCall); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, - new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null), CreateResponsePayload(), new Metadata()); @@ -301,7 +301,7 @@ namespace Grpc.Core.Internal.Tests var requestStream = new ClientRequestStream(asyncCall); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, - new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata()), + new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata(), null), CreateResponsePayload(), new Metadata()); @@ -325,7 +325,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.SendCompletionCallback.OnSendCompletion(true); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, - new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null), CreateResponsePayload(), new Metadata()); @@ -339,7 +339,7 @@ namespace Grpc.Core.Internal.Tests var requestStream = new ClientRequestStream(asyncCall); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, - new ClientSideStatus(Status.DefaultSuccess, new Metadata()), + new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null), CreateResponsePayload(), new Metadata()); @@ -395,7 +395,7 @@ namespace Grpc.Core.Internal.Tests Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count); fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); - fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null)); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); } @@ -408,7 +408,7 @@ namespace Grpc.Core.Internal.Tests var readTask = responseStream.MoveNext(); // try alternative order of completions - fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null)); fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -444,7 +444,7 @@ namespace Grpc.Core.Internal.Tests Assert.AreEqual("response1", responseStream.Current); var readTask3 = responseStream.MoveNext(); - fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null)); fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask3); @@ -484,7 +484,7 @@ namespace Grpc.Core.Internal.Tests var readTask = responseStream.MoveNext(); fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); - fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null)); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); } @@ -498,7 +498,7 @@ namespace Grpc.Core.Internal.Tests var readTask = responseStream.MoveNext(); fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); - fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null)); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -516,7 +516,7 @@ namespace Grpc.Core.Internal.Tests var readTask = responseStream.MoveNext(); fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); - fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata(), null)); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -639,7 +639,7 @@ namespace Grpc.Core.Internal.Tests ClientSideStatus CreateClientSideStatus(StatusCode statusCode) { - return new ClientSideStatus(new Status(statusCode, ""), new Metadata()); + return new ClientSideStatus(new Status(statusCode, ""), new Metadata(), null); } IBufferReader CreateResponsePayload() diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 6a7466ac278..37cf86016e1 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -553,7 +553,7 @@ namespace Grpc.Core.Internal if (deserializeException != null && receivedStatus.Status.StatusCode == StatusCode.OK) { - receivedStatus = new ClientSideStatus(DeserializeResponseFailureStatus, receivedStatus.Trailers); + receivedStatus = new ClientSideStatus(DeserializeResponseFailureStatus, receivedStatus.Trailers, receivedStatus.Error); } finishedStatus = receivedStatus; diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs index 50a626842dd..9d0e9ce41eb 100644 --- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs @@ -97,7 +97,9 @@ namespace Grpc.Core.Internal IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this); var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); - return new ClientSideStatus(status, metadata); + string error = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_recv_status_on_client_error_string(this)); + + return new ClientSideStatus(status, metadata, error); } public IBufferReader GetReceivedMessageReader() diff --git a/src/csharp/Grpc.Core/Internal/ClientSideStatus.cs b/src/csharp/Grpc.Core/Internal/ClientSideStatus.cs index d19c6538ba4..893849279ed 100644 --- a/src/csharp/Grpc.Core/Internal/ClientSideStatus.cs +++ b/src/csharp/Grpc.Core/Internal/ClientSideStatus.cs @@ -16,40 +16,25 @@ #endregion -using System; -using Grpc.Core; - namespace Grpc.Core.Internal { /// - /// Status + metadata received on client side when call finishes. + /// Status + metadata + error received on client side when call finishes. /// (when receive_status_on_client operation finishes). /// - internal struct ClientSideStatus + internal readonly struct ClientSideStatus { - readonly Status status; - readonly Metadata trailers; - - public ClientSideStatus(Status status, Metadata trailers) + public ClientSideStatus(Status status, Metadata trailers, string error) { - this.status = status; - this.trailers = trailers; + Status = status; + Trailers = trailers; + Error = error; } - public Status Status - { - get - { - return this.status; - } - } + public Status Status { get; } - public Metadata Trailers - { - get - { - return this.trailers; - } - } + public Metadata Trailers { get; } + + public string Error { get; } } }