Go微服务实战|第6章:gRPC Error Handling

  • 原创
  • Madman
  • /
  • /
  • 3
  • 14399 次阅读

Go 微服务实战.png

Synopsis: 本文描述了 gRPC 如何处理错误,如何返回内置的错误代码 error codes。更多详情可以阅读 https://grpc.io/docs/guides/error/ 和 http://avi.im/grpc-errors/

代码已上传到 https://github.com/wangy8961/grpc-go-tutorial/tree/v0.6 ,欢迎 star

1. Error status codes

当客户端成功调用 gRPC 服务端方法时,将返回 codes.OK 状态码,所有的状态码都定义在 google.golang.org/grpc/codes

如果发生错误,gRPC 会返回一个代表错误的状态码(比如 codes.InvalidArgument),并附带可选的字符串错误消息,该消息提供更详细的错误发生的原因说明信息

// A Code is an unsigned 32-bit error code as defined in the gRPC spec.
type Code uint32

const (
    // OK is returned on success.
    OK Code = 0

    // Canceled indicates the operation was canceled (typically by the caller).
    Canceled Code = 1

    // Unknown error. An example of where this error may be returned is
    // if a Status value received from another address space belongs to
    // an error-space that is not known in this address space. Also
    // errors raised by APIs that do not return enough error information
    // may be converted to this error.
    Unknown Code = 2

    // InvalidArgument indicates client specified an invalid argument.
    // Note that this differs from FailedPrecondition. It indicates arguments
    // that are problematic regardless of the state of the system
    // (e.g., a malformed file name).
    InvalidArgument Code = 3

    // DeadlineExceeded means operation expired before completion.
    // For operations that change the state of the system, this error may be
    // returned even if the operation has completed successfully. For
    // example, a successful response from a server could have been delayed
    // long enough for the deadline to expire.
    DeadlineExceeded Code = 4

    // NotFound means some requested entity (e.g., file or directory) was
    // not found.
    NotFound Code = 5

    // AlreadyExists means an attempt to create an entity failed because one
    // already exists.
    AlreadyExists Code = 6

    // PermissionDenied indicates the caller does not have permission to
    // execute the specified operation. It must not be used for rejections
    // caused by exhausting some resource (use ResourceExhausted
    // instead for those errors). It must not be
    // used if the caller cannot be identified (use Unauthenticated
    // instead for those errors).
    PermissionDenied Code = 7

    // ResourceExhausted indicates some resource has been exhausted, perhaps
    // a per-user quota, or perhaps the entire file system is out of space.
    ResourceExhausted Code = 8

    // FailedPrecondition indicates operation was rejected because the
    // system is not in a state required for the operation's execution.
    // For example, directory to be deleted may be non-empty, an rmdir
    // operation is applied to a non-directory, etc.
    FailedPrecondition Code = 9

    // Aborted indicates the operation was aborted, typically due to a
    // concurrency issue like sequencer check failures, transaction aborts,
    // etc.
    Aborted Code = 10

    // OutOfRange means operation was attempted past the valid range.
    // E.g., seeking or reading past end of file.
    OutOfRange Code = 11

    // Unimplemented indicates operation is not implemented or not
    // supported/enabled in this service.
    Unimplemented Code = 12

    // Internal errors. Means some invariants expected by underlying
    // system has been broken. If you see one of these errors,
    // something is very broken.
    Internal Code = 13

    // Unavailable indicates the service is currently unavailable.
    // This is a most likely a transient condition and may be corrected
    // by retrying with a backoff. Note that it is not always safe to retry
    // non-idempotent operations.
    Unavailable Code = 14

    // DataLoss indicates unrecoverable data loss or corruption.
    DataLoss Code = 15

    // Unauthenticated indicates the request does not have valid
    // authentication credentials for the operation.
    Unauthenticated Code = 16

    _maxCode = 17
)

2. 服务端返回错误

2.1 定义 Protocol Buffers

创建 grpc-go-tutorial/features/echopb/echo.proto 文件:

syntax = "proto3";

option go_package="echopb";

package echo;

// EchoRequest is the request for echo.
message EchoRequest {
    string message = 1;
}

// EchoResponse is the response for echo.
message EchoResponse {
    string message = 1;
}

// Echo is the echo service.
service Echo {
    // UnaryEcho is unary echo.
    rpc UnaryEcho(EchoRequest) returns (EchoResponse) {}
    // ServerStreamingEcho is server side streaming.
    rpc ServerStreamingEcho(EchoRequest) returns (stream EchoResponse) {}
    // ClientStreamingEcho is client side streaming.
    rpc ClientStreamingEcho(stream EchoRequest) returns (EchoResponse) {}
    // BidirectionalStreamingEcho is bidi streaming.
    rpc BidirectionalStreamingEcho(stream EchoRequest) returns (stream EchoResponse) {}
}

切换到 .proto 文件所在目录:

[root@CentOS ~]# cd grpc-go-tutorial/features/echopb/
[root@CentOS echopb]# protoc --go_out=plugins=grpc:. *.proto

2.2 服务端返回 codes.Unimplemented

正常情况下,服务端应该实现 echo.pb.goEchoServer 接口的所有方法(实现具体的业务逻辑):

// EchoServer is the server API for Echo service.
type EchoServer interface {
    // UnaryEcho is unary echo.
    UnaryEcho(context.Context, *EchoRequest) (*EchoResponse, error)
    // ServerStreamingEcho is server side streaming.
    ServerStreamingEcho(*EchoRequest, Echo_ServerStreamingEchoServer) error
    
                                
                            
  • alexander_guan
  • LILIannnna
  • 俊俊俊俊俊俊zzzz
  • wuleiyzu
  • amptyy
  • qq601046124
  • blake
  • B15030328
  • Peter Pan
  • raojingpeng
  • gitzh2017
  • jungle
  • zhouyi
  • chenfan
  • abc127546
  • zhuoqianmingyue
  • yangyang
  • Metauro
  • MseJue
  • linearlarry
  • yuchunyun
  • leon133
  • voidnil0
  • fissh
未经允许不得转载: LIFE & SHARE - 王颜公子 » Go微服务实战|第6章:gRPC Error Handling

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

3 条评论

guader
guader

请问客户端怎么判断服务端返回的错误是某个指定错误,一定要通过code或者message去判断是否相等吗? 话说我就是为了看这个来的。。。

Madman
Madman guader Author

是用返回的错误码,不是message,默认 gRPC 在 codes 中定义了一些常量来表示一些错误,你也可以按这种方式增加你自己的错误码。RPC 的客户端事先会从服务端拿到一份包含所有错误码的

guader
guader Madman

我已经用status.Convert去处理了

专题系列