trpc.group/trpc-go/trpc-go@v1.0.3/errs/README.zh_CN.md (about)

     1  [English](README.md) | 中文
     2  
     3  # tRPC-Go 错误码定义
     4  
     5  
     6  ## 前言
     7  
     8  所有语言的 tRPC 框架使用统一的错误定义,由错误码 `code` 和错误描述 `msg` 组成,这与 Golang 标准库的 error 只有一个字符串不同,所以 tRPC-Go 这边通过 errs 包封装了错误类型,方便用户使用。当用户需要返回错误时,使用 `errs.New(code, msg)` 来创建错误,而不是使用标准库的 `errors.New(msg)`,如:
     9  
    10  ```golang
    11  func (s *greeterServerImpl) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
    12      if failed { // 业务逻辑失败
    13          // 定义错误码,错误信息返回给上游
    14          return nil, errs.New(int(your-err-code), "your business error message")
    15      }
    16      return &pb.HelloRepley{}, nil // 业务逻辑成功
    17  }
    18  ```
    19  
    20  ## 错误码类型
    21  
    22  tRPC-Go 的错误码分框架错误码 `framework`,下游框架错误码 `callee framework`,业务错误码 `business`。
    23  
    24  ### 框架错误码
    25  
    26  当前自身服务的框架自动返回的错误码,如调用下游服务超时,解包错误等,tRPC 使用的所有框架错误码都定义在 [trpc.proto](https://github.com/trpc-group/trpc/blob/main/trpc/trpc.proto) 中。
    27  
    28  0~100 为服务端的错误,即当前服务在**框架网络层收到请求包之后,进入业务处理函数之前**出错,框架会返回错误给上游,业务是无感知的。在上游服务的视角来看就是[下游框架错误码](#下游框架错误码)。
    29  
    30  101~200 为客户端的错误,即调用下游服务时出现的客户端层面的错误。
    31  
    32  201~400 为流式错误。
    33  
    34  框架错误码日志表现如下:
    35  
    36  ```golang
    37  type:framework, code:101, msg:xxx timeout
    38  ```
    39  
    40  ### 下游框架错误码
    41  
    42  当前服务调用下游时,下游服务(被调服务)的框架返回的错误码,这对于下游服务的业务开发来说可能是无感知的,但很明确就是下游服务返回的错误,跟当前自身服务没有关系,当前服务是正常的,不过一般是由于自己参数错误引起下游出错。
    43  出现这个错误,请根据错误信息检查请求参数并与下游服务联调解决。
    44  
    45  一般日志表现如下:
    46  
    47  ```golang
    48  type:callee framework, code:12, msg:rpcname:xxx invalid
    49  ```
    50  
    51  ### 业务错误码
    52  
    53  当前服务调用下游时,下游服务的业务逻辑通过 `errs.New` 返回的错误码。注意:该错误类型是下游服务的业务逻辑返回的错误码,是下游服务定义的,具体含义需要查阅下游服务文档或咨询下游服务开发者。
    54  
    55  tRPC-Go 推荐:业务错误时,使用 `errs.New` 来返回业务错误码,而不是在应答包里面自己定义错误码,错误码和应答包是互斥的,所以如果返回了错误,框架会忽略应答包。
    56  
    57  建议用户自定义的错误码范围大于 10000。
    58  
    59  一般日志表现如下:
    60  
    61  ```golang
    62  type:business, code:10000, msg:xxx fail
    63  ```
    64  
    65  ## 错误码定义
    66  
    67  **注意:以下错误码说的是框架错误码和下游框架错误码。业务错误码是业务服务定义的,具体含义需要查阅下游服务文档或咨询下游服务开发者。错误码只是提供了概括性的错误类型,具体错误原因一定要仔细看错误详细信息。**
    68  
    69  | 错误码 | 含义                                                                                                                             |
    70  | :----: | :------------------------------------------------------------------------------------------------------------------------------- |
    71  |   0    | 成功                                                                                                                             |
    72  |   1    | 服务端解码错误,一般是上下游服务 pb 字段没有对齐或者没有同步更新,解包失败,上下游服务全部更新到 pb 最新版,保持 pb 同步即可解决 |
    73  |   2    | 服务端编码错误,序列化响应包失败,一般是 pb 字段设置问题,如把不可见字符的二进制数据设置到 string 字段里面了,具体看错误信息     |
    74  |   11   | 服务端没有相应的 service 实现                                                                                                    |
    75  |   12   | 服务端没有相应的接口实现,调用函数填错                                                                                           |
    76  |   21   | 服务端业务逻辑处理时间过长超时,超过了链路超时时间或者消息超时时间                                                               |
    77  |   22   | 服务端过载,一般是下游服务端使用了过载保护插件                                                                                   |
    78  |   23   | 请求被服务端限流                                                                                                                 |
    79  |   24   | 服务端全链路超时,即上游调用方给的超时时间过短,还来不及进入本服务的业务逻辑                                                     |
    80  |   31   | 服务端系统错误,一般是 panic 引起的错误,大概率是被调服务空指针,数组越界等                                                      |
    81  |   41   | 鉴权不通过                                                                                                                       |
    82  |   51   | 请求参数校验不通过                                                                                                               |
    83  |  101   | 请求在客户端调用超时                                                                                                             |
    84  |  102   | 客户端全链路超时,即当前发起 rpc 的超时时间过短,有可能是上游给的超时时间不够,也有可能是前面的 rpc 调用已经耗尽了大部分时间     |
    85  |  111   | 客户端连接错误,一般是下游没有监听该 ip:port,如下游启动失败                                                                     |
    86  |  121   | 客户端编码错误,序列化请求包失败                                                                                                 |
    87  |  122   | 客户端解码错误,一般是 pb 没有对齐                                                                                               |
    88  |  123   | 请求被客户端限流                                                                                                                 |
    89  |  124   | 客户端过载错误                                                                                                                   |
    90  |  131   | 客户端选 ip 路由错误,一般是服务名填错,或者该服务名下没有可用实例                                                               |
    91  |  141   | 客户端网络错误                                                                                                                   |
    92  |  151   | 响应参数校验不通过                                                                                                               |
    93  |  161   | 上游调用方提前取消请求                                                                                                           |
    94  |  171   | 客户端读取帧数据错误                                                                                                             |
    95  |  201   | 服务端流式网络错误                                                                                                               |
    96  |  351   | 客户端流式读取数据失败                                                                                                           |
    97  |  999   | 未明确的错误,一般是下游直接用 Golang 标准库 `errors.New(msg)` 返回了不带数字的错误了,没有用框架自带的 `errs.New(code, msg)`    |
    98  
    99  ## 实现
   100  
   101  tRPC-Go 中错误结构具体实现如下:
   102  
   103  ```golang
   104  type Error struct {
   105      Type int    // 错误码类型 1 框架错误码 2 业务错误码 3 下游框架错误码
   106      Code int32  // 错误码
   107      Msg  string // 错误信息描述
   108      Desc string // 错误额外描述,主要用于监控前缀,如 trpc 框架错误为 trpc 前缀,http 协议错误为 http 前缀,用户可以通过实现拦截器捕获该 err 并更改该字段实现上报任意前缀的监控
   109  }
   110  ```
   111  
   112  错误处理流程:
   113  
   114  - 当服务端通过 `errs.New` 返回业务错误时,框架会将该错误填入 trpc 协议头的业务错误 `func_ret` 字段里。
   115  - 当服务端通过 `errs.NewFrameError` 返回框架错误时,框架会将该错误填入 trpc 协议头的框架错误 `ret` 字段里。
   116  - 当服务端框架回包时,会判断是否有错误,有错误则会抛弃响应数据包,所以如果返回错误时,不要再试图通过响应包返回数据。
   117  - 当客户端发起 RPC 调用时,框架需要先执行编码等操作,再把请求发送到下游,如果在发出网络数据之前出错,则直接返回 `框架错误` 给用户;如果发送请求成功并收到回包,但从回包的协议头中解析出框架错误则返回 `下游框架错误`,如果解析出业务错误则返回 `业务错误`。