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


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

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

    服务端返回错误信息

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

    客户端解析错误信息

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

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

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

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

    1. //方式一
    2. return status.Error(codes.Code(5200), "create failed ")
    3. //方式二
    4. const(
    5. UserNotExist codes.Code = 5200
    6. )
    7. 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 错误消息类型:

    1. // The `Status` type defines a logical error model that is suitable for
    2. // different programming environments, including REST APIs and RPC APIs.
    3. message Status {
    4. // A simple error code that can be easily handled by the client. The
    5. // actual error code is defined by `google.rpc.Code`.
    6. int32 code = 1;
    7. // A developer-facing human-readable error message in English. It should
    8. // both explain the error and offer an actionable resolution to it.
    9. string message = 2;
    10. // Additional error information that the client code can use to handle
    11. // the error, such as retry info or a help link.
    12. repeated google.protobuf.Any details = 3;
    13. }

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

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

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

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

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

    1. s, _ := status.Newf(codes.InvalidArgument, "invalid input").WithDetails(&errdetails.BadRequest{
    2. FieldViolations: []*errdetails.BadRequest_FieldViolation{
    3. {
    4. Field: "SomeRequest.email_address",
    5. Description: "INVALID_EMAIL_ADDRESS",
    6. },
    7. {
    8. Field: "SomeRequest.username",
    9. Description: "INVALID_USER_NAME",
    10. },
    11. },
    12. })
    13. return s.Err()

  • 相关阅读:
    【测开求职】面试题:HR面相关的开放性问题
    技术对接76
    IDEA日常使用
    【OpenCV】基于opencv的视频间隔抽帧脚本
    HttpServletRequest接口详解,获取html用户输入的表单数据,HttpServletRequest请求域,请求转发机制
    算法|每日一题|统计能整除数字的位数
    Vue-Resource发送get-post-jsonp请求
    Linux下connect函数 阻塞 与 非阻塞 问题
    C++ builder 常见问题汇总
    torch-sparse安装错误; windows上面jps没有namenode;如何下载spark
  • 原文地址:https://blog.csdn.net/qq_40604313/article/details/126105265