question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Why is catch block called twice in Grpc Interceptor C#?

See original GitHub issue

I ran into a problem when I started to implement a global error handler for the grpc server service. The problem is that when I get a validation error, I don’t want to log it, but I want to return an RpcException with information to the client, and in other Exceptions I log it and return an unhandled error. The question is why do I repeatedly get into the catch block (Exception e) after I caught the ValidationException and threw the RpcException? To the fact that it is called twice, the logic I described above breaks down for me. The implementation is shown below:

public class ExceptionInterceptor : Interceptor
{
    private readonly ILogger<ExceptionInterceptor> _logger;

    public ExceptionInterceptor(ILogger<ExceptionInterceptor> logger)
    {
        _logger = logger;
    }

    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        try
        {
            return await continuation(request, context);
        }
        catch (ValidationException e)
        {
            var error = string.Join(Environment.NewLine, e.Errors.Select(p => p.ErrorMessage));
            throw new RpcException(new Status(StatusCode.InvalidArgument, error));
        }
        catch (Exception e)
        {
            _logger.LogError(e, "gRPC Exception");
            throw;
        }
    }
}

Interceptor registration:

services.AddGrpc(o =>
{
    o.Interceptors.Add<ExceptionInterceptor>();
});

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
JamesNKcommented, Oct 9, 2022

It sounds like a bug in Stashbox. I don’t know anything about that.

1reaction
JamesNKcommented, Oct 5, 2022

I couldn’t replicate this. When I register the interceptor and throw an error, the error is caught then rethrown as RpcException, and the other catch block does nothing.

Log output:

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\Development\Source\grpc-dotnet\examples\Reflector\Server
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 POST https://localhost:5001/greet.Greeter/SayHello application/grpc -
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'gRPC - /greet.Greeter/SayHello'
info: Grpc.AspNetCore.Server.ServerCallHandler[7]
      Error status code 'InvalidArgument' with detail 'Validation failed' raised.
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'gRPC - /greet.Greeter/SayHello'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/2 POST https://localhost:5001/greet.Greeter/SayHello application/grpc - - 200 0 application/grpc 1748.5373ms

Changes to register interceptor: https://github.com/JamesNK/grpc-dotnet/commit/7fff9da6a06dcec170786a9bb98006235085c020

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why is catch block called twice in Grpc Interceptor C#? - ...
The reason was that when we register the interceptor globally, it fires twice. If we register it for a specific service, then it...
Read more >
gRPC interceptors on .NET
Interceptors are a gRPC concept that allows apps to interact with incoming or outgoing gRPC calls. They offer a way to enrich the...
Read more >
Global error Handling in gRPC & gRPC status codes
The operation was aborted, typically due to a concurrency issue like sequencer check failures, transaction aborts, etc. AlreadyExists. Some ...
Read more >
grpc - Go
An RPC status is sent out (error or success). This occurs when the handler returns. SetHeader will fail if called after any of...
Read more >
Python Microservices With gRPC
In this tutorial, you'll learn how to build a robust and developer-friendly Python microservices infrastructure. You'll learn what microservices are and how ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found