3

我最近一直在尝试 gRPC 错误处理,并希望将我自己的 proto 消息传递给客户端(定义我自己的错误详细信息和内部错误代码)。在搜索之后,发现了几个使用 gRPC 状态包中的 WithDetails() 来附加自定义元数据的示例。我开始实施如下

gRPC 原型消息

message ErrorInfo {
    int64 error_code = 1;
    string error_message = 2;
    string resource_name = 3;
}

服务器端实现

// Frame the error message
        st := status.New(codes.NotFound, "object not found")
        errInfo := &api.ErrorInfo {
            ErrorCode: 100,
            ErrorMessage: "Fetching credential failed",
            ResourceName: req.GetBackupLocation().GetCloudCredential(),
        }
        var err error
        st, err = st.WithDetails(errInfo)
        if err != nil {
            // If this errored, it will always error
            // here, so better panic so we can figure
            // out why than have this silently passing.
            panic(fmt.Sprintf("Unexpected error attaching metadata: %v", err))
        }

        return  st.Err()

客户端实现

fmt.Printf("line 76 err :%v", err)
                st := status.Convert(err)
                for _, detail := range st.Details() {
                    switch t := detail.(type) {
                    case *api.ErrorInfo:
                        fmt.Printf("error code: %v", t.GetErrorCode())
                        fmt.Printf("error msg: %v", t.GetErrorMessage())
                        fmt.Printf("resource name: %v", t.GetResourceName())
                    }
                }

当我运行代码时,它命中了在服务器代码中添加的 Panic(),这意味着 WithDetails() 出错了。

为了进一步进行,消除了服务器端的恐慌,此客户端引发以下错误

:any: message type "" isn't linked inerror

问题:

  • WithDetails() 是否仅适用于 googleapis/rpc/errdetails 标准 gRPC 原型定义而不适用于自定义原型?
  • 查看 proto 文件和代码实现,我没有看到任何特定于 gRPC errdetails 包的内容。

  • 当我尝试使用此包中的 proto 消息时,它工作正常。

[注意:我使用的是gogo protobuf]

任何人都可以告诉我我在这里缺少什么吗?

4

2 回答 2

-1

我遇到了类似的错误(any: message type "" isn't linked in *errors.errorString)。就我而言,这是由于grpc.StatusAPI。

如果您使用的是 gogo proto,则需要导入/使用

"github.com/gogo/status"

代替

"google.golang.org/grpc/status"

于 2020-05-14T20:55:38.490 回答
-3

从我的角度来看,即使 GRPC API 允许,将业务逻辑错误与传输错误混合在一起也不应该被视为一种好的做法。为每个响应添加特殊ResultError结构(使用您自己的一组字段和代码)是报告请求处理状态的更干净和灵活的方式。

于 2020-04-26T21:59:55.907 回答