GRPC错误处理
今天来讲一讲 gRPC 错误处理的方式,以及如何自定义错误处理。当发起 gRPC 调用时,客户端会接受成功状态的响应或带有错误信息状态的错误响应。 考虑程序的健壮性,我们需要在编写客户端处理信息时,要处理所有可能的错误。编写服务端代码也要处理错误,并构建合适的错误状态码。 当 gRPC 发生错误时,会返回一个错误码。并附带一条可选的信息, 错误状态信息由一个整形状态码和一条字符串消息组成,适用于不同的语言实现。 下图展示了 gRPC 内置的错误码: 缺陷 gRPC 提供的错误模型非常有限,并且与底层的数据格式无关,最常用的数据格式就是 protocol buffers。 如果使用了 protocol buffers, google.rpc 提供了更丰富的错误模型,但语言兼容性待测试。 错误处理例子 接下来继续沿用前面的代码,来讲解如何运用错误处理。 假如我们需要在订单添加处理中处理非法 ID 请求。 如果我们传了一个不合法的 ID 如 -1,需要返回错误给客户端消费者。 func (s *server) AddOrder(ctx context.Context, orderReq *pb.Order) (*wrappers.StringValue, error) { if orderReq.Id == "-1" { log.Printf("Order ID is vaild : %s", orderReq.Id) errorStatus := status.New(codes.InvalidArgument, "Order ID is not valid") ds, err := errorStatus.WithDetails( &epb.BadRequest_FieldViolation{ Field: "ID", Description: fmt.Sprintf("Order ID received is not valid %s : %s", orderReq.Id, orderReq.Description), }, ) if err != nil { return nil, errorStatus.Err() } return nil, ds.Err() } orderMap[orderReq.Id] = *orderReq log.Println("Order : ", orderReq.Id, " -> Added") return &wrapper.StringValue{Value: "Order Added: " + orderReq.Id}, nil } 通过 status 包可以很方便的创建所需的错误码和相应错误详情。使用 Google API 的相应包可以设置更丰富的错误详情。 ...