11

I'm writing gRPC services using ASP.NET Core using GRPC.ASPNETCore.

I've tried to add an Exception Filter for gRPC methods like this

services.AddMvc(options =>
{
    options.Filters.Add(typeof(BaseExceptionFilter));
});

or using the UseExceptionHandler extension method like this

app.UseExceptionHandler(configure =>
{
    configure.Run(async e =>
    {
        Console.WriteLine("Exception test code");
    });
});

But both of them are not working (not intercepting code).

Is it possible to add global exception handler for gRPC services in ASP.NET Core?

I don't want to write try-catch code wrapper for each method I want to call.

Community
  • 1
  • 1
Dmitriy
  • 847
  • 17
  • 39
  • 1
    You should be able to use a gRPC server-side interceptor (which is a gRPC concept) - that can catch an handle any exceptions being thrown by your server-side handler methods. See e.g. https://github.com/grpc/grpc-dotnet/blob/098893e777049586b6f27d19bf255d18069593a2/examples/Logger/Server/Startup.cs#L33 – Jan Tattermusch Nov 28 '19 at 16:38
  • @Jan Tattermusch, yes, I've done this both on the client and server side. I hoped that it's possible to use ASP.NET Core exception nadling mechanism because it's easier to implement, but it's really no way. – Dmitriy Nov 29 '19 at 08:03
  • 1
    have you found any solution for this? I can see the log message in the console app, but can't find a way to write it to the disk – Thiago Custodio Mar 20 '20 at 16:10

1 Answers1

16

Add custom interceptor in Startup

services.AddGrpc(options =>
{
    {
        options.Interceptors.Add<ServerLoggerInterceptor>();
        options.EnableDetailedErrors = true;
    }
});

Create custom class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Core.Interceptors;
using Microsoft.Extensions.Logging;

namespace Systemx.WebService.Services
{
    public class ServerLoggerInterceptor : Interceptor
    {
        private readonly ILogger<ServerLoggerInterceptor> _logger;

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

        public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
            TRequest request,
            ServerCallContext context,
            UnaryServerMethod<TRequest, TResponse> continuation)
        {
            //LogCall<TRequest, TResponse>(MethodType.Unary, context);

            try
            {
                return await continuation(request, context);
            }
            catch (Exception ex)
            {
                // Note: The gRPC framework also logs exceptions thrown by handlers to .NET Core logging.
                _logger.LogError(ex, $"Error thrown by {context.Method}.");                

                throw;
            }
        }
       
    }
}
valentasm
  • 2,137
  • 23
  • 24