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>();
});
The reason was that when we register the interceptor globally, it fires twice. If we register it for a specific service, then it works once.The answer is:
services.AddGrpc()
.AddServiceOptions<MyService>(o =>
{
o.Interceptors.Add<ExceptionInterceptor>();
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.