RpcException有相对应的重载:具体如下,可以自定义异常返回的信息
客户端也可以通过拦截器处理错误(实现客户端事件,如AsyncUnaryCall):
using Grpc.Core; using Grpc.Core.Interceptors; using Microsoft.Extensions.Logging; using System.Threading.Tasks; namespace ConsoleAppGRPC.Logging { public class LoggerInterceptor : Interceptor { private readonly ILogger<LoggerInterceptor> _logger; public LoggerInterceptor(ILogger<LoggerInterceptor> logger) { _logger = logger; } public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>( TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation) { LogCall(context.Method); var call = continuation(request, context); return new AsyncUnaryCall<TResponse>(HandleResponse(call.ResponseAsync), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose); } private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t) { try { var response = await t; _logger.LogDebug($"Response received: {response}"); return response; } catch (RpcException ex) { _logger.LogError($"Call error: {ex.Message}"); return default; } } private void LogCall<TRequest, TResponse>(Method<TRequest, TResponse> method) where TRequest : class where TResponse : class { _logger.LogDebug($"Starting call. Type: {method.Type}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}"); } } }使用方法:
using DemoGrpc.Domain.Entities; using DemoGrpc.Protobufs; using Microsoft.Extensions.DependencyInjection; using System; using System.Linq; using System.Threading.Tasks; using static DemoGrpc.Protobufs.CountryService; using Microsoft.Extensions.Logging; using ConsoleAppGRPC.Logging; namespace ConsoleAppGRPC { class Program { static async Task Main(string[] args) { var services = new ServiceCollection(); services.AddScoped<LoggerInterceptor>(); services.AddLogging(logging => { logging.AddConsole(); logging.SetMinimumLevel(LogLevel.Debug); }); services.AddGrpcClient<CountryServiceClient>(o => { o.Address = new Uri("https://localhost:5001"); }).AddInterceptor<LoggerInterceptor>(); var provider = services.BuildServiceProvider(); var client = provider.GetRequiredService<CountryServiceClient>(); var logger = provider.GetRequiredService<ILogger<Program>>(); var countries = (await client.GetAllAsync(new EmptyRequest()))?.Countries.Select(x => new Country { CountryId = x.Id, Description = x.Description, CountryName = x.Name }).ToList(); if (countries != null) { logger.LogInformation("Found countries"); countries.ForEach(x => Console.WriteLine($"Found country {x.CountryName} ({x.CountryId}) {x.Description}")); } else { logger.LogDebug("No countries found"); } } } }