gRPC异常处理流程设计

我的博客阅读本文

2021-06-30新增了部分代码演示,请参考
2022-02-17更新,之前思路有局限,这里不推荐使用异常来处理业务上的异常,基于此认知,更推荐业务上能够约定固定的数据结构ResultDTO,能够描述业务上的异常,比如错误码等信息,”异常“的处理,更推荐是在不可预知的非义务异常上进行兜底,目前已在todo list中,准备重新设计,来补足业务上已知的异常处理方式。

1. 核心诉求

  • 服务提供方异常能够被服务消费方感知
  • 异常分类处理:
    1. 业务异常,需要返回对应的错误码,方便服务消费方进行国际化文案的提示+日志。
    2. 非业务异常(比如NPE),需要返回内容给到服务消费方感知。
  • 拓展性&流程尽可能简单

2. 方案选择

2.1. 直接调用OnError方法,传递Status包装异常后返回

例子:

try {
   

}catch (Throwable t) {
   
// Throwable t | StreamObserver<xxx> responseObserver
responseObserver.onError(Status.UNKNOWN
                  .withDescription(t.getMessage())
                  .withCause(t)
                  .asRuntimeException());
}

这个方式客户端可以感知到,但是可能能够放入的信息有限,只能是一个字符串,只能在withDescription这个参数里,如果要多个参数,可能借助一些序列化框架转化为字符串进行转换。

2.2. 借助protobuf 的 OneOf语法

protobuf文件:

message Request {
   
  int32 number = 1;
}

message SuccessResponse {
   
  int32 result = 1;
}

enum ErrorCode {
   
  ABOVE_20 = 0;
  BELOW_2 = 1;
}

message ErrorResponse {
   
  int32 input = 1;
  ErrorCode error_code = 2;
}

// 重点是这里,回调有两种,一个成功,一个失败
message Response {
   
  oneof response {
   
    SuccessResponse success_response = 1;
    ErrorResponse error_response = 2;
  }
}

service CalculatorService {
   
  rpc findSquare(Request) returns (Response) {
   };
}

Java代码:

@Override
public void findSquare(Request request, StreamObserver<Response> responseObserver) {
   
    Response.Builder builder = Response.newBuilder();
		try {
   
			// 异常业务
		}catch (Throwable t) {
   
				// 有异常的话返回错误的Message类型
        ErrorResponse errorResponse = ErrorResponse.newBuilder()
								// 业务异常
                .setInput(xxx)
								// 业务错误代码
                .setErrorCode(errorCode)
                .build();
        builder.setErrorResponse(errorResponse);
				return;
		
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值