当前位置: 首页 > 知识库问答 >
问题:

使用gRPC状态包中的WithDetails()传递自定义proto消息

冯霖
2023-03-14

我最近一直在尝试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(),这意味着Wit详细信息()出错了。

为了进一步进行,删除了服务器端的死机,该客户端抛出以下错误

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

问题:

>

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

    当我尝试使用这个包中的proto消息时,它工作得很好。

    [注意:我使用的是gogo pro buf]

    谁能告诉我我在这里错过了什么?

  • 共有2个答案

    马坚白
    2023-03-14

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

    石喜
    2023-03-14

    我遇到了一个类似的错误(any:消息类型""没有在*errors.errorString中链接)。在我的例子中,这是由于grpc. statusAPI。

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

    github.com/gogo/status”

    而不是

    “google.golang.org/grpc/status”

     类似资料:
    • 自定义的状态栏覆盖在系统状态栏上,能够在自定义的状态栏中显示文字信息,可以隐藏自定义的状态栏,显示系统状态栏。 作者@贺坤Smaile 说:之前逛街看到移动做推广,有一个定位应用挺好的,合理的利用了状态栏,做了一些消息提醒和隐藏动画,自己回家就做了一个这样的demo,效果很不错,一个多月之前写的,看到有人求,分享出来。 [Code4App.com]

    • 顺便说一下,在使用/而不是发射器时,我遇到了同样的问题。我已经决定给你们举这个例子,因为它很容易理解和再现。

    • 但是控制台显示一个错误: 未捕获的 DOMException:无法在 “History” 上执行 'pushState':无法克隆 Symbol(react.element)。 这是什么意思?对此我能做些什么?

    • 我正在尝试学习“react router”,我正在开发一个应用程序,它有一个输入字段,可以为您提供一个下拉列表,其中包含指向欧洲各个火车站的链接,当您单击该链接时,它将呈现一个组件,在本例中为

    • 我有这样一个gRPC API定义(来自Akka docs示例),但要长得多(4000行,仅是服务部分)。 然而,RPC列表现在变得太长了,我想以某种方式将其“分解”为多个文件,以便文件更具可读性。像这样的 即使只是在不同的文件中分别定义RPC,然后编写类似的内容也会对我有所帮助: 是否有可能在gRPC协议定义中以某种方式“组合”服务?

    • 我考虑在项目中使用fluent-http。 所以我尝试注入: 返回正确的字符串,但似乎没有使用状态代码。在这两种情况下,响应都有一个代码HTTP200。 注意:我发现一些状态代码是预先实现的: null