首页 > 解决方案 > 如何正确传播 gRPC 错误 Spring-boot

问题描述

我一直在关注这篇文章。

我试图在 Spring-boot 应用程序中优雅地处理 gRPC 错误,主要目标是能够在 gRPC 客户端中获取错误状态。

按照上面的文章,我坚持为异常添加拦截器。如何在 Spring-boot 应用程序中执行此操作?通过@Configuration?

或者一般来说,您如何通过 gRPC 调用的客户端获得正确的错误消息?

标签: spring-booterror-handlinggrpc

解决方案


如果您可以使用yidongnan/grpc-spring-boot-starter将您的 gRPC 应用程序转换为 Spring Boot,则可以简化错误处理,然后您可以编写,@GrpcAdvice类似于 Spring Boot@ControllerAdvice

@GrpcAdvice
public class ExceptionHandler {

  @GrpcExceptionHandler(ResourceNotFoundException.class)
  public StatusRuntimeException handleResourceNotFoundException(ResourceNotFoundException cause) {
    var errorMetaData = cause.getErrorMetaData();
    var errorInfo =
        ErrorInfo.newBuilder()
            .setReason("Resource not found")
            .setDomain("Product")
            .putAllMetadata(errorMetaData)
            .build();
    var status =
        com.google.rpc.Status.newBuilder()
            .setCode(Code.NOT_FOUND.getNumber())
            .setMessage("Resource not found")
            .addDetails(Any.pack(errorInfo))
            .build();
    return StatusProto.toStatusRuntimeException(status);
  }
}

在客户端,您可以捕获此异常并将 registerUserResponse 解包为:

} catch (StatusRuntimeException error) {
   com.google.rpc.Status status = io.grpc.protobuf.StatusProto.fromThrowable(error);
   RegisterUserResponse registerUserResponse = null;
   for (Any any : status.getDetailsList()) {
     if (!any.is(RegisterUserResponse.class)) {
       continue;
     }
     registerUserResponse = any.unpack(ErrorInfo.class);
   }
   log.info(" Error while calling product service, reason {} ", registerUserResponse.getValidationErrorsList());
   //Other action
 }

我写了一篇关于 gRPC 错误处理的详细文章 -在 gRPC 中正确处理错误


推荐阅读