[gRPC] .NET Core 에서 gRPC 오류 처리하는 방법
- gRPC
- 2023. 3. 1. 00:38
참고 사이트
gRPC 인터셉터에 의한 서버 예외 처리
- Interecptor 클래스에는 gRPC 요청을 가로채기 위한 많은 메서드가 있습니다.
- 여기서는 서버 측 수신 호출에 대한 최상의 방법은
UnaryServerHandler
메서드를 사용하는 것입니다. - 다음은 서버 측 인터셉터 코드 예제 입니다.
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 (Exception exception)
{
//... Handle of error logic
}
}
}
- 다음 단계는 유용한 인터셉터를 IoC 컨테이너에 등록하는 것입니다.
public void ConfigureServices(IServiceCollection services)
{
// Classic sample..
services.AddGrpc(
options =>
{
options.Interceptors.Add<ExceptionInterceptor>();
});
// CodeFirst sample..
services.AddCodeFirstGrpc(
options =>
{
options.Interceptors.Add<ExceptionInterceptor>();
});
}
{% include adsense.html %}
gRPC 클라이언트의 예외 처리
- 앞서, 서버 측 인터셉터 코드를 작성하였습니다.
- 하지만 만약 서버가 gRPC 클라이언트 측에 사용자 지정 예외를 throw 하면 어떻게 될까요?
- 생각과는 다르게 Client 에서는 Server 가 throw 한 사용자 정의 예외를 수신하지 않고, 아래 코드가 예상한 것과는 다르게 동작하지 않게 됩니다.
try
{
await grpc.SendWeatherForecastGeneratedEvent(new SendWeatherForecastEventCommand());
}
catch(CustomWeatherException exception)
{
}
- 실제로 Client 에서 받게되는 예외는 사용자 정의 예외가 아닌
RpcException
예외를 받게 됩니다. - 서버 측에서 이 예외의 내용을 Status 객체로 지정할 수 있습니다.
- 상태에는 호출 코드(gRPC 호출 코드) 및 세부 정보에 대한 정보가 포함됩니다.
- 앞에서 작성했던 서버 측 인터 셉터 코드를 다음과 같이 수정 하였습니다.
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 (CustomWeatherException weatherException)
{
throw new RpcException(new Status(StatusCode.InvalidArgument, "weather is terrible"));
}
catch (Exception exception)
{
throw new RpcException(new Status(StatusCode.Internal, exception.ToString()));
}
}
}
- 위 코드를 작성하고, 예외가 발생하게 되면 Client 는 Server 에서 어떤 에러가 발생했는지 정확히 알 수 있습니다.
gRPC 요청 상태 코드 관리
- gRPC 요청 상태를 코드로 관리할 수 있습니다.
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 (CustomWeatherException weatherException)
{
var httpContext = context.GetHttpContext();
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
throw new RpcException(new Status(StatusCode.InvalidArgument, "weather is terrible"));
}
catch (Exception exception)
{
var httpContext = context.GetHttpContext();
httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
throw new RpcException(new Status(StatusCode.Internal, exception.ToString()));
}
}
}
ServerCallContext
인수에서 httpContext 에 대한 정보를 얻을 수 있고 200 상태 코드를 재정의할 수 있습니다.
728x90
'gRPC' 카테고리의 다른 글
[gRPC] gRPC 프로토콜 버퍼 기초 - 메시지 정의 2 (0) | 2023.03.02 |
---|---|
[gRPC] gRPC 인터셉터 (0) | 2023.03.01 |
[인공지능] Tensorflow Serving gRPC C# 구현 (0) | 2023.02.27 |
[gRPC] gRPC C# Server/Client 예제 (0) | 2023.02.26 |
[C#] .NET FileUpload gPRC Service Poc (0) | 2023.02.02 |
이 글을 공유하기