diff --git a/src/csharp/Grpc.Core.Api/Status.cs b/src/csharp/Grpc.Core.Api/Status.cs index 5c3ff18e22e..72d9e5371b8 100644 --- a/src/csharp/Grpc.Core.Api/Status.cs +++ b/src/csharp/Grpc.Core.Api/Status.cs @@ -42,6 +42,8 @@ namespace Grpc.Core /// /// Creates a new instance of Status. + /// Users should not use this constructor, except for creating instances for testing. + /// The debug error string should only be populated by gRPC internals. /// /// Status code. /// Detail. diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs index 331c3321e14..d06c55040be 100644 --- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs @@ -139,6 +139,26 @@ namespace Grpc.Core.Tests Assert.AreEqual(0, ex2.Trailers.Count); } + [Test] + public void UnaryCall_StatusDebugErrorStringNotTransmittedFromServer() + { + helper.UnaryHandler = new UnaryServerMethod((request, context) => + { + context.Status = new Status(StatusCode.Unauthenticated, "", "this DebugErrorString value should not be transmitted to the client"); + return Task.FromResult(""); + }); + + var ex = Assert.Throws(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); + Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); + Assert.IsTrue(ex.Status.DebugErrorString.Contains("Error received from peer")); // a different debug error string set by grpc client + Assert.AreEqual(0, ex.Trailers.Count); + + var ex2 = Assert.ThrowsAsync(async () => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); + Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); + Assert.IsTrue(ex2.Status.DebugErrorString.Contains("Error received from peer")); // a different debug error string set by grpc client + Assert.AreEqual(0, ex2.Trailers.Count); + } + [Test] public void UnaryCall_ServerHandlerSetsStatusAndTrailers() { diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs index d0f5c100be0..a8470af549e 100644 --- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs @@ -92,8 +92,8 @@ namespace Grpc.Core.Internal UIntPtr detailsLength; IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength); string details = MarshalUtils.PtrToStringUTF8(detailsPtr, (int)detailsLength.ToUInt32()); - string error = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_recv_status_on_client_error_string(this)); - var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details, error); + string debugErrorString = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_recv_status_on_client_error_string(this)); + var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details, debugErrorString); IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this); var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);