grpc / grpc/grpc-dotnet

Is it possible to intercept/handle errors thrown by Grpc.AspNetCore.Server.ServerCallHandler?

Open
#1,077 6 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
C#
Stars
4.5k
Forks
836
Avg merge
6d 3h
Merged PRs (30d)
7

Description

Hi, I'm working on error handling for a project and I'm trying to understand if it's possible to intercept or handle errors that seems to be thrown very early in the pipeline. I've tried interceptors, but seems like we never get there. Is there any suggested way to handle this kind of errors?

```
2020-10-14 14:18:08 [ERR] Grpc.AspNetCore.Server.ServerCallHandler
{"EventId":{"Id":14,"Name":"ErrorReadingMessage"},"RequestId":"0HM3G7CQSMESD:00000001","RequestPath":"/MyProject.SomeService/SetDisplayName","SpanId":"|bde9d0fa-4c539042cc801db0.","TraceId":"bde9d0fa-4c539042cc801db0","ParentId":""}
Error reading message.
System.FormatException: Unexpected Guid length: 37
at ProtoBuf.Internal.ThrowHelper.Format(String message) in /_/src/protobuf-net.Core/Internal/ThrowHelper.cs:line 34
at ProtoBuf.Internal.GuidHelper.Read(State& state) in /_/src/protobuf-net.Core/Internal/GuidHelper.cs:line 74
at proto_8(State& , SetDisplayNameRequest )
at ProtoBuf.Internal.Serializers.SimpleCompiledSerializer`1.ProtoBuf.Serializers.ISerializer.Read(State& state, T value)
at ProtoBuf.ProtoReader.State.ReadAsRoot[T](T value, ISerializer`1 serializer)
at ProtoBuf.ProtoReader.State.DeserializeRoot[T](T value, ISerializer`1 serializer)
at ProtoBuf.Meta.TypeModel.Deserialize[T](ReadOnlySequence`1 source, T value, Object userState)
at ProtoBuf.Grpc.Configuration.ProtoBufMarshallerFactory.ContextualDeserialize[T](DeserializationContext context)
at Grpc.AspNetCore.Server.Internal.PipeExtensions.ReadSingleMessageAsync[T](PipeReader input, HttpContextServerCallContext serverCallContext, Func`2 deserializer)

2020-10-14 14:18:08 [ERR] Grpc.AspNetCore.Server.ServerCallHandler
{"EventId":{"Id":6,"Name":"ErrorExecutingServiceMethod"},"RequestId":"0HM3G7CQSMESD:00000001","RequestPath":"/MyProject.SomeService/SetDisplayName","SpanId":"|bde9d0fa-4c539042cc801db0.","TraceId":"bde9d0fa-4c539042cc801db0","ParentId":""}
Error when executing service method 'SetDisplayName'.
System.FormatException: Unexpected Guid length: 37
at ProtoBuf.Internal.ThrowHelper.Format(String message) in /_/src/protobuf-net.Core/Internal/ThrowHelper.cs:line 34
at ProtoBuf.Internal.GuidHelper.Read(State& state) in /_/src/protobuf-net.Core/Internal/GuidHelper.cs:line 74
at proto_8(State& , SetDisplayNameRequest )
at ProtoBuf.Internal.Serializers.SimpleCompiledSerializer`1.ProtoBuf.Serializers.ISerializer.Read(State& state, T value)
at ProtoBuf.ProtoReader.State.ReadAsRoot[T](T value, ISerializer`1 serializer)
at ProtoBuf.ProtoReader.State.DeserializeRoot[T](T value, ISerializer`1 serializer)
at ProtoBuf.Meta.TypeModel.Deserialize[T](ReadOnlySequence`1 source, T value, Object userState)
at ProtoBuf.Grpc.Configuration.ProtoBufMarshallerFactory.ContextualDeserialize[T](DeserializationContext context)
at Grpc.AspNetCore.Server.Internal.PipeExtensions.ReadSingleMessageAsync[T](PipeReader input, HttpContextServerCallContext serverCallContext, Func`2 deserializer)
at Grpc.AspNetCore.Server.Internal.CallHandlers.UnaryServerCallHandler`3.HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext)
at Grpc.AspNetCore.Server.Internal.CallHandlers.ServerCallHandlerBase`3.g__AwaitHandleCall|8_0(HttpContextServerCallContext serverCallContext, Method`2 method, Task handleCall)
```

Or am I stuck with these errors and have to rely on _Grpc.AspNetCore.Server.GrpcServiceOptions.EnableDetailedErrors_ to get a more detailed error? The issue with this method might be that I don't know which details that are leaked to the consumer, also the following error gives the status code _Unknown_, when it maybe could be a an _InvalidArgument_ instead?

Thanks for your help.
/Erik

Contributor guide

Open the contributing guide

Research direction

Start with Grpc.AspNetCore.Server.Internal.PipeExtensions.ReadSingleMessageAsync and the Grpc.AspNetCore.Server.Internal.CallHandlers.ServerCallHandlerBase path shown in the trace, then review interceptor handling and GrpcServiceOptions.EnableDetailedErrors. Determine whether deserialization errors can be intercepted and mapped to a chosen status without leaking details; done means the supported behavior and configuration point are documented or covered by a test.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.