Skip to content

Commit 0d35b5a

Browse files
authored
Don't log message read cancellation as an error in client (#724)
1 parent 63d5ac2 commit 0d35b5a

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

src/Grpc.Net.Client/Internal/StreamExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,9 @@ private static Status CreateUnknownMessageEncodingMessageStatus(string unsupport
173173
GrpcCallLog.ReceivedMessage(logger);
174174
return message;
175175
}
176-
catch (Exception ex)
176+
catch (Exception ex) when (!(ex is OperationCanceledException && cancellationToken.IsCancellationRequested))
177177
{
178+
// Don't write error when user cancels read
178179
GrpcCallLog.ErrorReadingMessage(logger, ex);
179180
throw;
180181
}

test/Grpc.Net.Client.Tests/HttpContentClientStreamReaderTests.cs

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@
1717
#endregion
1818

1919
using System;
20+
using System.Linq;
2021
using System.Net;
2122
using System.Net.Http;
2223
using System.Threading;
2324
using System.Threading.Tasks;
2425
using Greet;
2526
using Grpc.Core;
2627
using Grpc.Net.Client.Internal;
27-
using Grpc.Net.Client.Tests.Infrastructure;
2828
using Grpc.Tests.Shared;
29-
using Microsoft.Extensions.Logging.Abstractions;
29+
using Microsoft.Extensions.Logging;
30+
using Microsoft.Extensions.Logging.Testing;
3031
using NUnit.Framework;
3132

3233
namespace Grpc.Net.Client.Tests
@@ -48,7 +49,10 @@ public async Task MoveNext_TokenCanceledBeforeCall_ThrowError()
4849
return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content));
4950
});
5051

51-
var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient });
52+
var testSink = new TestSink(e => e.LogLevel >= LogLevel.Error);
53+
var testLoggerFactory = new TestLoggerFactory(testSink, enabled: true);
54+
55+
var channel = CreateChannel(httpClient, loggerFactory: testLoggerFactory);
5256
var call = CreateGrpcCall(channel);
5357
call.StartServerStreaming(new HelloRequest());
5458

@@ -60,6 +64,8 @@ public async Task MoveNext_TokenCanceledBeforeCall_ThrowError()
6064
var ex = await ExceptionAssert.ThrowsAsync<RpcException>(() => moveNextTask).DefaultTimeout();
6165

6266
Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
67+
68+
Assert.AreEqual(0, testSink.Writes.Count);
6369
}
6470

6571
[Test]
@@ -76,7 +82,10 @@ public async Task MoveNext_TokenCanceledBeforeCall_ThrowOperationCanceledExcepti
7682
return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content));
7783
});
7884

79-
var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient, ThrowOperationCanceledOnCancellation = true });
85+
var testSink = new TestSink(e => e.LogLevel >= LogLevel.Error);
86+
var testLoggerFactory = new TestLoggerFactory(testSink, enabled: true);
87+
88+
var channel = CreateChannel(httpClient, loggerFactory: testLoggerFactory, throwOperationCanceledOnCancellation: true);
8089
var call = CreateGrpcCall(channel);
8190
call.StartServerStreaming(new HelloRequest());
8291

@@ -86,6 +95,8 @@ public async Task MoveNext_TokenCanceledBeforeCall_ThrowOperationCanceledExcepti
8695
// Assert
8796
Assert.IsTrue(moveNextTask.IsCompleted);
8897
await ExceptionAssert.ThrowsAsync<OperationCanceledException>(() => moveNextTask).DefaultTimeout();
98+
99+
Assert.AreEqual(0, testSink.Writes.Count);
89100
}
90101

91102
[Test]
@@ -101,7 +112,10 @@ public async Task MoveNext_TokenCanceledDuringCall_ThrowError()
101112
return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content));
102113
});
103114

104-
var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient });
115+
var testSink = new TestSink(e => e.LogLevel >= LogLevel.Error);
116+
var testLoggerFactory = new TestLoggerFactory(testSink, enabled: true);
117+
118+
var channel = CreateChannel(httpClient, loggerFactory: testLoggerFactory);
105119
var call = CreateGrpcCall(channel);
106120
call.StartServerStreaming(new HelloRequest());
107121

@@ -116,6 +130,8 @@ public async Task MoveNext_TokenCanceledDuringCall_ThrowError()
116130
var ex = await ExceptionAssert.ThrowsAsync<RpcException>(() => moveNextTask).DefaultTimeout();
117131

118132
Assert.AreEqual(StatusCode.Cancelled, ex.StatusCode);
133+
134+
Assert.AreEqual(0, testSink.Writes.Count);
119135
}
120136

121137
[Test]
@@ -131,7 +147,10 @@ public async Task MoveNext_TokenCanceledDuringCall_ThrowOperationCanceledOnCance
131147
return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content));
132148
});
133149

134-
var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient, ThrowOperationCanceledOnCancellation = true });
150+
var testSink = new TestSink(e => e.LogLevel >= LogLevel.Error);
151+
var testLoggerFactory = new TestLoggerFactory(testSink, enabled: true);
152+
153+
var channel = CreateChannel(httpClient, loggerFactory: testLoggerFactory, throwOperationCanceledOnCancellation: true);
135154
var call = CreateGrpcCall(channel);
136155
call.StartServerStreaming(new HelloRequest());
137156

@@ -144,6 +163,8 @@ public async Task MoveNext_TokenCanceledDuringCall_ThrowOperationCanceledOnCance
144163
cts.Cancel();
145164

146165
await ExceptionAssert.ThrowsAsync<OperationCanceledException>(() => moveNextTask).DefaultTimeout();
166+
167+
Assert.AreEqual(0, testSink.Writes.Count);
147168
}
148169

149170
[Test]
@@ -157,7 +178,10 @@ public async Task MoveNext_MultipleCallsWithoutAwait_ThrowError()
157178
return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.OK, content));
158179
});
159180

160-
var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient });
181+
var testSink = new TestSink(e => e.LogLevel >= LogLevel.Error);
182+
var testLoggerFactory = new TestLoggerFactory(testSink, enabled: true);
183+
184+
var channel = CreateChannel(httpClient, loggerFactory: testLoggerFactory);
161185
var call = CreateGrpcCall(channel);
162186
call.StartServerStreaming(new HelloRequest());
163187

@@ -170,6 +194,11 @@ public async Task MoveNext_MultipleCallsWithoutAwait_ThrowError()
170194

171195
var ex = await ExceptionAssert.ThrowsAsync<InvalidOperationException>(() => moveNextTask2).DefaultTimeout();
172196
Assert.AreEqual("Can't read the next message because the previous read is still in progress.", ex.Message);
197+
198+
Assert.AreEqual(1, testSink.Writes.Count);
199+
var write = testSink.Writes.ElementAt(0);
200+
Assert.AreEqual("ReadMessageError", write.EventId.Name);
201+
Assert.AreEqual(ex, write.Exception);
173202
}
174203

175204
private static GrpcCall<HelloRequest, HelloReply> CreateGrpcCall(GrpcChannel channel)
@@ -182,5 +211,17 @@ private static GrpcCall<HelloRequest, HelloReply> CreateGrpcCall(GrpcChannel cha
182211
new CallOptions(),
183212
channel);
184213
}
214+
215+
private static GrpcChannel CreateChannel(HttpClient httpClient, ILoggerFactory? loggerFactory = null, bool? throwOperationCanceledOnCancellation = null)
216+
{
217+
return GrpcChannel.ForAddress(
218+
httpClient.BaseAddress,
219+
new GrpcChannelOptions
220+
{
221+
HttpClient = httpClient,
222+
LoggerFactory = loggerFactory,
223+
ThrowOperationCanceledOnCancellation = throwOperationCanceledOnCancellation ?? false
224+
});
225+
}
185226
}
186227
}

0 commit comments

Comments
 (0)