Go Action: Error Handling In gRPC

Go Action: Error Handling In gRPC. gRPC generally avoids defining errors within messages. After all, each gRPC service inherently comes with an error retur。

分享
gopher Querying and troubleshooting errors
generated By DALLE-3

gRPC generally avoids defining errors within messages. After all, each gRPC service inherently comes with an error return value, serving as a dedicated channel for error transmission. All error returns in gRPC should either be nil or an error generated by status.Status. This ensures that errors can be directly recognized by the calling Client.

1. Basic Usage

Simply returning upon encountering a Go error won’t be recognizable by downstream clients. The proper approach is:

  • Call the status.New method and pass an appropriate error code to generate a status.Status object.
  • Call the status.Err method to generate an error recognizable by the calling party, then return.
st := status.New(codes.NotFound, "some description")   
err := st.Err()

The error code passed in is of type codes.Code. Alternatively, you can use status.Error for a more convenient method that eliminates manual conversion.

err := status.Error(codes.NotFound, "some description")

2. Advanced Usage

The aforementioned errors have a limitation: the error codes defined by code.Code only cover certain scenarios and cannot comprehensively express the error scenarios encountered in business.

gRPC provides a mechanism to supplement information within errors: the status.WithDetails method.

Clients can directly retrieve the contents by converting the error back to status.Status and using the status.Details method.

status.Details returns a slice, which is a slice of interface{}. However, Go automatically performs type conversion, allowing direct usage through assertion.

Server-Side Example

  • • Generate a status.Status object
  • • Populate additional error information
func ErrorWithDetails() error {   
    st := status.Newf(codes.Internal, fmt.Sprintf("something went wrong: %v", "api.Getter"))   
    v := &errdetails.PreconditionFailure_Violation{ //errDetails   
       Type:        "test",   
       Subject:     "12",   
       Description: "32",   
    }   
    br := &errdetails.PreconditionFailure{}   
    br.Violations = append(br.Violations, v)   
    st, _ = st.WithDetails(br)   
    return st.Err()   
}

Client-Side Example

  • • Parse error information after RPC error
  • • Retrieve error details directly through assertion
resp, err := odinApp.CreatePlan(cli.StaffId.AssetId, gentRatePlanMeta(cli.StaffId))   
​   
  if status.Code(err) != codes.InvalidArgument {   
    logger.Error("create plan error:%v", err)   
  } else {   
    for _, d := range status.Convert(err).Details() {   
      //    
      switch info := d.(type) {   
      case *errdetails.QuotaFailure:   
        logger.Info("Quota failure: %s", info)   
      case *errdetails.PreconditionFailure:   
        detail := d.(*errdetails.PreconditionFailure).Violations   
        for _, v1 := range detail {   
          logger.Info(fmt.Sprintf("details: %+v", v1))   
        }   
      case *errdetails.ResourceInfo:   
        logger.Info("ResourceInfo: %s", info)   
   
      case *errdetails.BadRequest:   
        logger.Info("ResourceInfo: %s", info)   
   
      default:   
        logger.Info("Unexpected type: %s", info)   
      }   
    }   
  }   
  logger.Infof("create plan success,resp=%v", resp)

Principles

How are these errors passed to the calling Client? They are placed in metadata, then in the HTTP header. Metadata is in the format of key-value pairs. In error transmission, the key is a fixed value: grpc-status-details-bin. The value is encoded by proto and is binary-safe. Most languages have implemented this mechanism.

Note

gRPC imposes restrictions on response headers, with a limit of 8K, so errors should not be too large.

Reference:

文章索引

阅读更多

那些意外变成特性的 Bug:当代码漏洞改写计算史

那些意外变成特性的 Bug:当代码漏洞改写计算史

那些意外变成特性的 Bug:当代码漏洞改写计算史. 比起草台班子将错就错的神话,面对异常数据时的观测定力才是真的 社交网络上常年流传着一类爽文:某家公司的程序员把代码写崩了,结果不仅没被开除,这个 Bug 反而成了拳头产品,妥妥的爽文主角剧本。 最常被搬出来的有三个:Audio Hijack 写错试用期拯救公。

By huizhou92