OperationCanceledException thrown when canceling a CancelationToken does not reference the token canceled
See original GitHub issueWhat version of gRPC and what language are you using?
Grpc.Net.Client v2.51.0, .NET C#, Blazor WebAssembly
What operating system (Linux, Windows,…) and version?
WebAssembly (browser) - .NET
What runtime / compiler are you using (e.g. .NET Core SDK version dotnet --info
)
.NET SDK 7.0.2
What did you do?
If you cancel a CancelationToken provided to the gRPC client, the OperationCanceledException thrown does not reference the token.
Context: Many implementations use this pattern to “catch” the cancelation:
catch (Exception e)
{
if (e is OperationCanceledException oce && oce.CancellationToken == cancellationToken)
{
// No-op; we canceled the operation, so it's fine to suppress this exception.
}
e.g. Blazor’s Virtualize
component: https://github.com/dotnet/aspnetcore/blob/dfab67748084f120472e634a975b3c45150f608b/src/Components/Web/src/Virtualization/Virtualize.cs#L378-L383
What did you expect to see?
- The
OperationCanceledException.CancellationToken
(inRpcException.DebugException
) should be the originalCancellationToken
canceled. - In case of cancellation, the
OperationFailedException
should not be wrapped byRpcException
. It does not make sense as there is literally no use case where you would take advantage of having aRpcException
instead of the very specificOperationCanceledException
being caught by the caller expecting cancellation (such asVirtualize
component in Blazor).
What did you see instead?
OperationCanceledException.CancellationToken
is null
.
OperationCanceledException
is masked by RpcException
which implies need for “correcting” interceptor.
Anything else we should know about your project / environment?
I created a simple repro with Blazor-Virtualize. https://github.com/hakenr/VirtualizeGrpcRepro
The repro includes an active interceptor which “fixes” the error (for the AsyncUnaryCall
):
https://github.com/hakenr/VirtualizeGrpcRepro/blob/master/BlazorGrpcWebCodeFirst/Client/CancellationWorkaroundGrpcClientInterceptor.cs
If you remove the registration of CancellationWorkaroundGrpcClientInterceptor
from BlazorGrpcWebCodeFirst.Client/Program.cs
(line 18) you immediately see the result - the OperationFailedException
not being caught by Virtualize
, which breaks the app.
Issue Analytics
- State:
- Created 8 months ago
- Comments:5 (2 by maintainers)
Ok. There is an internal CancellationTokenSource for each gRPC call. I think there is a way to cancel it so that the reported token is the original one. Might be able to fix this in the gRPC client so your workaround isn’t needed.
There is a
ThrowOperationCanceledOnCancellation
option on the gRPC channel.I agree btw, but we chose to it this way for backwards compact with gRPC.Core