gRPC 服务器错误处理程序 golang

问题描述 投票:0回答:3

我想了解 golang、gRPC 和 protobuf 的良好实践。

我正在实现以下 gRPC 服务

service MyService {
   rpc dosomethink(model.MyModel) returns (model.Model) {
     option (google.api.http) = { post: "/my/path" body: "" };
   }
}

我编译了 protobuf。事实上,protobuf 给我们提供了一个从 http 到 grpc 的 httpproxy。

实现该服务的代码:

import "google.golang.org/grpc/status"

func (Abcd) Dosomethink(c context.Context, sessionRequest *model.MyModel) (*model.Model, error) {

   return nil, status.New(400,"Default error message for 400")
}

我想要一个 400 http 错误(在 http 代理中),并显示消息“400 的默认错误消息”,该消息有效,但 http 错误始终为 500。

您知道有关此的任何帖子或文档吗?

http go grpc protoc
3个回答
11
投票

您需要返回空的

model.Model
对象,以便 protobuf 能够正确序列化消息。

尝试

import "google.golang.org/grpc/status"

func (Abcd) Dosomethink(c context.Context, sessionRequest *model.MyModel) (*model.Model, error) {

   return &model.Model{}, status.Error(400,"Default error message for 400")
}

11
投票

错误处理程序:

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
return data, status.Errorf(
            codes.InvalidArgument,
            fmt.Sprintf("Your message", req.data),
        )

需要有关错误处理的更多信息,请查看下面的链接。

https://grpc.io/docs/guides/error.html

http://avi.im/grpc-errors/


0
投票

在 gRPC 中,我们永远不应该在成功响应中返回错误。应该就像我们返回 successResponse 或返回 errorResponse。如果我们返回例如 errorResponse 那么 successResponse 将是

nil

Golang 有一个名为

status
的包,广泛用于错误处理。它有一个内部函数
Error()
将其转换为返回的
error
对象。

// status.proto
message Status {
  // The status code, which should be an enum value of [google.rpc.Code]
  int32 code = 1;

  // error-message
  string message = 2;

  // A list of messages that carry the error details.
  repeated google.protobuf.Any details = 3;
}

因此,我们应该在

code
字段中发送 grpc 错误代码。我们可以在
message
字段中发送与发生的错误相关的一般消息或错误代码,例如“VALIDATION_ERROR”、“AUTH_ERROR”等。并且,附加信息或堆栈跟踪或开发人员错误消息应在
details
字段中发送。

示例1:

 err := status.Errorf(codes.InvalidArgument, "First Name is required")

示例2:

 //error.proto
 message ErrorDetails {
   string code = 1;
   string additional_info = 2;
 }

 err := status.Errorf(codes.InvalidArgument, "First Name is required")
 err, _ := err.WithDetails(&ErrorDetails{
   Code: "VALIDATION_ERROR",
   AdditionalInfo: "Error occured at third-party API"
 })

我们还可以创建类似于 Status 的自定义结构,它应该实现 2 个方法 -

Error()
GRPCStatus()
,gRPC 将负责其余工作。

注意:以防万一,我们使用 grpc-gateway 并通过代理为 grpc 和 http 服务器提供服务。在该场景中,我们可以使用

WithErrorHandler
创建自定义拦截器,将
status
对象隐藏为对客户端更友好的错误对象。

© www.soinside.com 2019 - 2024. All rights reserved.