protobuf-net / protobuf-net.Grpc

GRPC bindings for protobuf-net and grpc-dotnet
Other
847 stars 107 forks source link

RpcException StatusCode=Unknown Detail=Exception was thrown by handler #225

Open freica opened 2 years ago

freica commented 2 years ago

Perhaps this is a general GRPC issue and not a protobuf-net, I don't know.

I am migrating a WCF solution using .NET Framework 4.8 protobuf-net.Grpc.Native and Code-First. On streaming special data from server to client I get the RcpException at client side, while other test-data on same entities could be transfered well.

Some days ago I get the same exception, if the transfer-entities don't have an empty ctor.

On sending at server side I don't see any exception. channel.Writer.WriteAsync(eventInfo);

It's really hard to find the matter! So do you have any, idea how to localize the matter? Is it a server or client-side exception?

This is the exception:

Exception occured: message=Grpc.Core.RpcException: Status(StatusCode="Unknown", Detail="Exception was thrown by handler.", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1645111986.734000000","description":"Error received from peer ipv6:[::1]:30051","file":"..\..\..\src\core\lib\surface\call.cc","file_line":1068,"grpc_message":"Exception was thrown by handler.","grpc_status":2}")
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   bei Grpc.Core.Internal.ClientResponseStream`2.<MoveNext>d__5.MoveNext() in /var/local/git/grpc/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs:Zeile 59.
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   bei ProtoBuf.Grpc.Internal.Reshape.<ServerStreamingAsyncImpl>d__14`2.MoveNext() in /_/src/protobuf-net.Grpc/Internal/Reshape.cs:Zeile 340.
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1.GetResult(Int16 token)
   bei ProtoBuf.Grpc.Internal.Reshape.<ServerStreamingAsyncImpl>d__14`2.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult(Int16 token)
   bei System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
   bei CA.Event.gRPC.EventMonitorClient3.<notifyAsync>d__23.MoveNext() in D:\PvSrc\PvWeb\Common\Event_from_Bb\EventServiceRpc\gRPC\EventMonitorClient3.cs:Zeile 87.
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
mgravell commented 2 years ago

Yes, this is gRPC and outside of my control. I have logged an issue with the suggested fix.

However! Have you tried installing protobuf-net.BuildTools? This should add an analyzer that spots common errors, at build time. If it doesn't spot this one: we can fix that (in the analyzer).

mgravell commented 2 years ago

Cross-reference: https://github.com/grpc/grpc/issues/24784

freica commented 2 years ago

Thank you for cross-referencing!

I am using code-first, so are you sure that protobuf-net.BuildTools brings the right analyzer for this?

mgravell commented 2 years ago

Yes, I'm sure.

freica commented 2 years ago

Ok, but I don't see any info how to use it without proto files. I added the package protobuf-net.BuildTools to my project. But don't get any info from analyzer at the output window of VS.

mgravell commented 2 years ago

Ok. The test here is to add two fields on the same type with the same field number. If the IDE starts shouting at you: it is installed. The csproj entry should look something like shown here (but with the current version):

https://protobuf-net.github.io/protobuf-net/build_tools.html

Note: I can't guarantee we detect the constructor missing, but if we don't: we can add it.

Pete-PlaytimeSolutions commented 2 years ago

I'm having a similar issue, where I am throwing an RpcException on the server, but it is always coming back the incorrect sStatusCode="Unknown" on the client.

NOTE: A string representation of the correct status code can be seen in the ex.Status.Detail of the Unknown exception, but it is not easily parsed.

e..g. Server: new RpcException(new Status(StatusCode.NotFound, "record not found."))

Client receives RpcException: Status(StatusCode="Unknown", Detail="Status(StatusCode="NotFound", Detail="record not found.")")

mgravell commented 2 years ago

@Pete-PlaytimeSolutions happy to take a look, but I'd need some kind of repro steps, and knowledge of which transports you're using at each end (by which I mean: the Google native layer or the Microsoft managed layer). This exception doesn't usually come from this library - we just provide serialization - but I may be able to find the problem anyway, as I'm very familiar with all the relevant code here.

Also: knowledge of the API kind: unary, client streaming, server streaming, or duplex. And info on whether simple exception handling is enabled.

Pete-PlaytimeSolutions commented 2 years ago

Hi @mgravell Ended up finding the issue, I had an Interceptor configured, for ExceptionHandling, it was hitting a catch all block throwing a new RpcException(new Status(StatusCode.Unknown, ex.Message))

My bad, thanks for you help.

freica commented 2 years ago

Sorry, but my IDE isn't shouting - but keep in mind: no *.proto, .NET Framework 4.8 !?

    <PackageReference Include="protobuf-net.BuildTools">
      <Version>3.0.115</Version>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="protobuf-net.Grpc.Native">
      <Version>1.0.152</Version>
    </PackageReference>

Dupplicate order:

        [XmlRoot("EventInfo")]
    [DataContract]
    public class EventInfo
    {
        [DataMember(Name = "EventId", Order = 1)]
        long eventId;
        [DataMember(Name = "ObjName", Order = 1)]
        private string objName;
        [DataMember(Name = "ItemDsgn", Order = 3)]
        private string itemDsgn;
...
mgravell commented 2 years ago

Ahhhhh! Right; to avoid accidentally shouting at people, currently we only enable the analyzer when it detects types annotated with the library's own attributes, i.e. [ProtoContract]/[ProtoMember] - as we can be fully sure that the consumer is intending them for use with protobuf-net

freica commented 2 years ago

Ok, I could rename the attributes, but keep in mind protobuf-net would be also a good solution for migrating WCF.

Could I use for a transitional period both attributes parallel, so I could use WCF + gRCP in this time?

and yes a missing parameterless ctor is also logged. grafik