如何使用grpc从服务端像向客户端传递错误信息

 当我们在使用grpc来提供服务的时候,不免会返回某些错误的信息,grpc为我们提供了定义好的错误码,错误码也非常有限。

以 服务端:go   客户端:python 为例

服务端返回错误信息

return status.Errorf(codes.InvalidArgument,"invalid args: %v" +err)

客户端解析错误信息

# 1、一般返回的是服务端自定义字符串信息
e.details() 
# 2、一般是grpc的状态码信息
status_code = e.code()
status_code.name  # 对应状态码名字(string)
status_code.value  # 对应状态码(int)

grpc为我们提供了16种“开箱即用”的状态码

但是往往我们需要的错误信息是与我们的系统数据相关:所以如何实现扩展呢

1、通过自定义状态码来实现?

//方式一
return status.Error(codes.Code(5200), "create failed ")


//方式二
const(
	UserNotExist codes.Code = 5200
)
return status.Error(UserNotExist, "create failed ")

实际上 ,客户端接收error时,code信息是2,unknown(这是因为我们自定义的状态码并不存在于grpc约定好的错误码信息中)

2、通过定义proto的message来实现?

Google 基于自身业务, 有了一套错误扩展 https://cloud.google.com/apis/design/errors#error_model, 简单来说就是自己定义了一个 protobuf 错误消息类型:

// The `Status` type defines a logical error model that is suitable for
// different programming environments, including REST APIs and RPC APIs.
message Status {
  // A simple error code that can be easily handled by the client. The
  // actual error code is defined by `google.rpc.Code`.
  int32 code = 1;

  // A developer-facing human-readable error message in English. It should
  // both explain the error and offer an actionable resolution to it.
  string message = 2;

  // Additional error information that the client code can use to handle
  // the error, such as retry info or a help link.
  repeated google.protobuf.Any details = 3;
}

此段代码转自:gRPC 扩展错误处理 - 墨天轮 (modb.pro)

那么问题来了, 如何传递这个非标准的错误扩展消息呢? 答案是放在 trailing response metadata
中, key 为 grpc-status-details-bin

此方法搭配 status.Details();但我没有试验成功

s, _ := status.Newf(codes.InvalidArgument, "invalid input").WithDetails(&Status)

这个方法还能将具体的proto字段指定出来并增加描述

s, _ := status.Newf(codes.InvalidArgument, "invalid input").WithDetails(&errdetails.BadRequest{
	FieldViolations: []*errdetails.BadRequest_FieldViolation{
		{
			Field:       "SomeRequest.email_address",
			Description: "INVALID_EMAIL_ADDRESS",
		},
		{
			Field:       "SomeRequest.username",
			Description: "INVALID_USER_NAME",
		},
	},
})

return s.Err()

在C#中,gRPC是一个高性能、开源的RPC框架,它结合了Protocol Buffers(protobuf)HTTP/2协议。FlatBuffers是一种高效的二进制数据序列化库,特别适合在网络间传输结构化的数据。 **案例概述:** 1. **服务端:** - **定义.proto文件**: 首先,在.proto文件中定义服务消息结构。例如,创建一个`User.grpc.proto`文件,声明用户服务及其请求/响应消息。 ```proto service UserService { rpc CreateUser(User) returns (int32); rpc GetUser(int32) returns (User); } message User { string name = 1; int32 id = 2; } ``` 2. **使用FlatBuffers**: 定义FlatBuffer版本的User对象,然后生成C#绑定代码。通过`dotnet FlatBuffers`命令行工具生成`UserService`相关的C#类。 3. **编写gRPC服务端**: 使用生成的类来实现UserService,包括CreateUserGetUser等方法,并处理FlatBuffer编码解码。 ```csharp public class UserService : UserServiceBase { // ... 实现FlatBuffer接收返回逻辑 } ``` 4. **启动gRPC服务器**: 创建一个gRPC服务器实例,监听指定端口并注册UserService实例。 5. **客户端:** - 同样,生成客户端的FlatBuffers代码gRPC客户端类。 - 客户端通过调用`UserService` API与服务交互,传递接收FlatBuffer数据。 ```csharp var client = new UserServiceClient(channel); await client.CreateUserAsync(..., userInFlatBuffer); ``` **相关问题--:** 1. gRPC在C#中如何进行序列化反序列化? 2. 如何处理FlatBuffers在跨语言通信中的性能优化? 3. gRPCRESTful API相比,有哪些优点?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值