Merge pull request #8531 from gyuho/error

*: deprecate grpc.Code, grpc.ErrorDesc
This commit is contained in:
Gyu-Ho Lee 2017-09-12 03:52:30 -07:00 committed by GitHub
commit bb4e0473ae
12 changed files with 146 additions and 114 deletions

View File

@ -33,6 +33,7 @@ import (
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive" "google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
) )
var ( var (
@ -478,14 +479,14 @@ func isHaltErr(ctx context.Context, err error) bool {
if err == nil { if err == nil {
return false return false
} }
code := grpc.Code(err) ev, _ := status.FromError(err)
// Unavailable codes mean the system will be right back. // Unavailable codes mean the system will be right back.
// (e.g., can't connect, lost leader) // (e.g., can't connect, lost leader)
// Treat Internal codes as if something failed, leaving the // Treat Internal codes as if something failed, leaving the
// system in an inconsistent state, but retrying could make progress. // system in an inconsistent state, but retrying could make progress.
// (e.g., failed in middle of send, corrupted frame) // (e.g., failed in middle of send, corrupted frame)
// TODO: are permanent Internal errors possible from grpc? // TODO: are permanent Internal errors possible from grpc?
return code != codes.Unavailable && code != codes.Internal return ev.Code() != codes.Unavailable && ev.Code() != codes.Internal
} }
func toErr(ctx context.Context, err error) error { func toErr(ctx context.Context, err error) error {
@ -496,7 +497,8 @@ func toErr(ctx context.Context, err error) error {
if _, ok := err.(rpctypes.EtcdError); ok { if _, ok := err.(rpctypes.EtcdError); ok {
return err return err
} }
code := grpc.Code(err) ev, _ := status.FromError(err)
code := ev.Code()
switch code { switch code {
case codes.DeadlineExceeded: case codes.DeadlineExceeded:
fallthrough fallthrough

View File

@ -26,8 +26,8 @@ import (
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/mvcc/mvccpb"
"google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
type leasingKV struct { type leasingKV struct {
@ -282,7 +282,10 @@ func (lkv *leasingKV) acquire(ctx context.Context, key string, op v3.Op) (*v3.Tx
return resp, nil return resp, nil
} }
// retry if transient error // retry if transient error
if _, ok := err.(rpctypes.EtcdError); ok || grpc.Code(err) != codes.Unavailable { if _, ok := err.(rpctypes.EtcdError); ok {
return nil, err
}
if ev, _ := status.FromError(err); ev.Code() != codes.Unavailable {
return nil, err return nil, err
} }
} }

View File

@ -22,6 +22,7 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
type rpcFunc func(ctx context.Context) error type rpcFunc func(ctx context.Context) error
@ -35,12 +36,16 @@ func isReadStopError(err error) bool {
return true return true
} }
// only retry if unavailable // only retry if unavailable
return grpc.Code(err) != codes.Unavailable ev, _ := status.FromError(err)
return ev.Code() != codes.Unavailable
} }
func isWriteStopError(err error) bool { func isWriteStopError(err error) bool {
return grpc.Code(err) != codes.Unavailable || ev, _ := status.FromError(err)
grpc.ErrorDesc(err) != "there is no address available" if ev.Code() != codes.Unavailable {
return true
}
return rpctypes.ErrorDesc(err) != "there is no address available"
} }
func (c *Client) newRetryWrapper(isStop retryStopErrFunc) retryRpcFunc { func (c *Client) newRetryWrapper(isStop retryStopErrFunc) retryRpcFunc {

View File

@ -15,110 +15,112 @@
package rpctypes package rpctypes
import ( import (
"google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
var (
// server-side error // server-side error
ErrGRPCEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided") var (
ErrGRPCKeyNotFound = grpc.Errorf(codes.InvalidArgument, "etcdserver: key not found") ErrGRPCEmptyKey = status.New(codes.InvalidArgument, "etcdserver: key is not provided").Err()
ErrGRPCValueProvided = grpc.Errorf(codes.InvalidArgument, "etcdserver: value is provided") ErrGRPCKeyNotFound = status.New(codes.InvalidArgument, "etcdserver: key not found").Err()
ErrGRPCLeaseProvided = grpc.Errorf(codes.InvalidArgument, "etcdserver: lease is provided") ErrGRPCValueProvided = status.New(codes.InvalidArgument, "etcdserver: value is provided").Err()
ErrGRPCTooManyOps = grpc.Errorf(codes.InvalidArgument, "etcdserver: too many operations in txn request") ErrGRPCLeaseProvided = status.New(codes.InvalidArgument, "etcdserver: lease is provided").Err()
ErrGRPCDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request") ErrGRPCTooManyOps = status.New(codes.InvalidArgument, "etcdserver: too many operations in txn request").Err()
ErrGRPCCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted") ErrGRPCDuplicateKey = status.New(codes.InvalidArgument, "etcdserver: duplicate key given in txn request").Err()
ErrGRPCFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision") ErrGRPCCompacted = status.New(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted").Err()
ErrGRPCNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded") ErrGRPCFutureRev = status.New(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision").Err()
ErrGRPCNoSpace = status.New(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded").Err()
ErrGRPCLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found") ErrGRPCLeaseNotFound = status.New(codes.NotFound, "etcdserver: requested lease not found").Err()
ErrGRPCLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists") ErrGRPCLeaseExist = status.New(codes.FailedPrecondition, "etcdserver: lease already exists").Err()
ErrGRPCMemberExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: member ID already exist") ErrGRPCMemberExist = status.New(codes.FailedPrecondition, "etcdserver: member ID already exist").Err()
ErrGRPCPeerURLExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: Peer URLs already exists") ErrGRPCPeerURLExist = status.New(codes.FailedPrecondition, "etcdserver: Peer URLs already exists").Err()
ErrGRPCMemberNotEnoughStarted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: re-configuration failed due to not enough started members") ErrGRPCMemberNotEnoughStarted = status.New(codes.FailedPrecondition, "etcdserver: re-configuration failed due to not enough started members").Err()
ErrGRPCMemberBadURLs = grpc.Errorf(codes.InvalidArgument, "etcdserver: given member URLs are invalid") ErrGRPCMemberBadURLs = status.New(codes.InvalidArgument, "etcdserver: given member URLs are invalid").Err()
ErrGRPCMemberNotFound = grpc.Errorf(codes.NotFound, "etcdserver: member not found") ErrGRPCMemberNotFound = status.New(codes.NotFound, "etcdserver: member not found").Err()
ErrGRPCRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large") ErrGRPCRequestTooLarge = status.New(codes.InvalidArgument, "etcdserver: request is too large").Err()
ErrGRPCRequestTooManyRequests = grpc.Errorf(codes.ResourceExhausted, "etcdserver: too many requests") ErrGRPCRequestTooManyRequests = status.New(codes.ResourceExhausted, "etcdserver: too many requests").Err()
ErrGRPCRootUserNotExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: root user does not exist") ErrGRPCRootUserNotExist = status.New(codes.FailedPrecondition, "etcdserver: root user does not exist").Err()
ErrGRPCRootRoleNotExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: root user does not have root role") ErrGRPCRootRoleNotExist = status.New(codes.FailedPrecondition, "etcdserver: root user does not have root role").Err()
ErrGRPCUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists") ErrGRPCUserAlreadyExist = status.New(codes.FailedPrecondition, "etcdserver: user name already exists").Err()
ErrGRPCUserEmpty = grpc.Errorf(codes.InvalidArgument, "etcdserver: user name is empty") ErrGRPCUserEmpty = status.New(codes.InvalidArgument, "etcdserver: user name is empty").Err()
ErrGRPCUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found") ErrGRPCUserNotFound = status.New(codes.FailedPrecondition, "etcdserver: user name not found").Err()
ErrGRPCRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists") ErrGRPCRoleAlreadyExist = status.New(codes.FailedPrecondition, "etcdserver: role name already exists").Err()
ErrGRPCRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found") ErrGRPCRoleNotFound = status.New(codes.FailedPrecondition, "etcdserver: role name not found").Err()
ErrGRPCAuthFailed = grpc.Errorf(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password") ErrGRPCAuthFailed = status.New(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password").Err()
ErrGRPCPermissionDenied = grpc.Errorf(codes.PermissionDenied, "etcdserver: permission denied") ErrGRPCPermissionDenied = status.New(codes.PermissionDenied, "etcdserver: permission denied").Err()
ErrGRPCRoleNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role is not granted to the user") ErrGRPCRoleNotGranted = status.New(codes.FailedPrecondition, "etcdserver: role is not granted to the user").Err()
ErrGRPCPermissionNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: permission is not granted to the role") ErrGRPCPermissionNotGranted = status.New(codes.FailedPrecondition, "etcdserver: permission is not granted to the role").Err()
ErrGRPCAuthNotEnabled = grpc.Errorf(codes.FailedPrecondition, "etcdserver: authentication is not enabled") ErrGRPCAuthNotEnabled = status.New(codes.FailedPrecondition, "etcdserver: authentication is not enabled").Err()
ErrGRPCInvalidAuthToken = grpc.Errorf(codes.Unauthenticated, "etcdserver: invalid auth token") ErrGRPCInvalidAuthToken = status.New(codes.Unauthenticated, "etcdserver: invalid auth token").Err()
ErrGRPCInvalidAuthMgmt = grpc.Errorf(codes.InvalidArgument, "etcdserver: invalid auth management") ErrGRPCInvalidAuthMgmt = status.New(codes.InvalidArgument, "etcdserver: invalid auth management").Err()
ErrGRPCNoLeader = grpc.Errorf(codes.Unavailable, "etcdserver: no leader") ErrGRPCNoLeader = status.New(codes.Unavailable, "etcdserver: no leader").Err()
ErrGRPCNotLeader = grpc.Errorf(codes.Unavailable, "etcdserver: not leader") ErrGRPCNotLeader = status.New(codes.Unavailable, "etcdserver: not leader").Err()
ErrGRPCNotCapable = grpc.Errorf(codes.Unavailable, "etcdserver: not capable") ErrGRPCNotCapable = status.New(codes.Unavailable, "etcdserver: not capable").Err()
ErrGRPCStopped = grpc.Errorf(codes.Unavailable, "etcdserver: server stopped") ErrGRPCStopped = status.New(codes.Unavailable, "etcdserver: server stopped").Err()
ErrGRPCTimeout = grpc.Errorf(codes.Unavailable, "etcdserver: request timed out") ErrGRPCTimeout = status.New(codes.Unavailable, "etcdserver: request timed out").Err()
ErrGRPCTimeoutDueToLeaderFail = grpc.Errorf(codes.Unavailable, "etcdserver: request timed out, possibly due to previous leader failure") ErrGRPCTimeoutDueToLeaderFail = status.New(codes.Unavailable, "etcdserver: request timed out, possibly due to previous leader failure").Err()
ErrGRPCTimeoutDueToConnectionLost = grpc.Errorf(codes.Unavailable, "etcdserver: request timed out, possibly due to connection lost") ErrGRPCTimeoutDueToConnectionLost = status.New(codes.Unavailable, "etcdserver: request timed out, possibly due to connection lost").Err()
ErrGRPCUnhealthy = grpc.Errorf(codes.Unavailable, "etcdserver: unhealthy cluster") ErrGRPCUnhealthy = status.New(codes.Unavailable, "etcdserver: unhealthy cluster").Err()
ErrGRPCCorrupt = grpc.Errorf(codes.DataLoss, "etcdserver: corrupt cluster") ErrGRPCCorrupt = status.New(codes.DataLoss, "etcdserver: corrupt cluster").Err()
errStringToError = map[string]error{ errStringToError = map[string]error{
grpc.ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey, ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey,
grpc.ErrorDesc(ErrGRPCKeyNotFound): ErrGRPCKeyNotFound, ErrorDesc(ErrGRPCKeyNotFound): ErrGRPCKeyNotFound,
grpc.ErrorDesc(ErrGRPCValueProvided): ErrGRPCValueProvided, ErrorDesc(ErrGRPCValueProvided): ErrGRPCValueProvided,
grpc.ErrorDesc(ErrGRPCLeaseProvided): ErrGRPCLeaseProvided, ErrorDesc(ErrGRPCLeaseProvided): ErrGRPCLeaseProvided,
grpc.ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps, ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps,
grpc.ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey, ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey,
grpc.ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted, ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted,
grpc.ErrorDesc(ErrGRPCFutureRev): ErrGRPCFutureRev, ErrorDesc(ErrGRPCFutureRev): ErrGRPCFutureRev,
grpc.ErrorDesc(ErrGRPCNoSpace): ErrGRPCNoSpace, ErrorDesc(ErrGRPCNoSpace): ErrGRPCNoSpace,
grpc.ErrorDesc(ErrGRPCLeaseNotFound): ErrGRPCLeaseNotFound, ErrorDesc(ErrGRPCLeaseNotFound): ErrGRPCLeaseNotFound,
grpc.ErrorDesc(ErrGRPCLeaseExist): ErrGRPCLeaseExist, ErrorDesc(ErrGRPCLeaseExist): ErrGRPCLeaseExist,
grpc.ErrorDesc(ErrGRPCMemberExist): ErrGRPCMemberExist, ErrorDesc(ErrGRPCMemberExist): ErrGRPCMemberExist,
grpc.ErrorDesc(ErrGRPCPeerURLExist): ErrGRPCPeerURLExist, ErrorDesc(ErrGRPCPeerURLExist): ErrGRPCPeerURLExist,
grpc.ErrorDesc(ErrGRPCMemberNotEnoughStarted): ErrGRPCMemberNotEnoughStarted, ErrorDesc(ErrGRPCMemberNotEnoughStarted): ErrGRPCMemberNotEnoughStarted,
grpc.ErrorDesc(ErrGRPCMemberBadURLs): ErrGRPCMemberBadURLs, ErrorDesc(ErrGRPCMemberBadURLs): ErrGRPCMemberBadURLs,
grpc.ErrorDesc(ErrGRPCMemberNotFound): ErrGRPCMemberNotFound, ErrorDesc(ErrGRPCMemberNotFound): ErrGRPCMemberNotFound,
grpc.ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge, ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge,
grpc.ErrorDesc(ErrGRPCRequestTooManyRequests): ErrGRPCRequestTooManyRequests, ErrorDesc(ErrGRPCRequestTooManyRequests): ErrGRPCRequestTooManyRequests,
grpc.ErrorDesc(ErrGRPCRootUserNotExist): ErrGRPCRootUserNotExist, ErrorDesc(ErrGRPCRootUserNotExist): ErrGRPCRootUserNotExist,
grpc.ErrorDesc(ErrGRPCRootRoleNotExist): ErrGRPCRootRoleNotExist, ErrorDesc(ErrGRPCRootRoleNotExist): ErrGRPCRootRoleNotExist,
grpc.ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist, ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist,
grpc.ErrorDesc(ErrGRPCUserEmpty): ErrGRPCUserEmpty, ErrorDesc(ErrGRPCUserEmpty): ErrGRPCUserEmpty,
grpc.ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound, ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound,
grpc.ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist, ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist,
grpc.ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound, ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound,
grpc.ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed, ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed,
grpc.ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied, ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied,
grpc.ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted, ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted,
grpc.ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted, ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted,
grpc.ErrorDesc(ErrGRPCAuthNotEnabled): ErrGRPCAuthNotEnabled, ErrorDesc(ErrGRPCAuthNotEnabled): ErrGRPCAuthNotEnabled,
grpc.ErrorDesc(ErrGRPCInvalidAuthToken): ErrGRPCInvalidAuthToken, ErrorDesc(ErrGRPCInvalidAuthToken): ErrGRPCInvalidAuthToken,
grpc.ErrorDesc(ErrGRPCInvalidAuthMgmt): ErrGRPCInvalidAuthMgmt, ErrorDesc(ErrGRPCInvalidAuthMgmt): ErrGRPCInvalidAuthMgmt,
grpc.ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader, ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader,
grpc.ErrorDesc(ErrGRPCNotLeader): ErrGRPCNotLeader, ErrorDesc(ErrGRPCNotLeader): ErrGRPCNotLeader,
grpc.ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable, ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable,
grpc.ErrorDesc(ErrGRPCStopped): ErrGRPCStopped, ErrorDesc(ErrGRPCStopped): ErrGRPCStopped,
grpc.ErrorDesc(ErrGRPCTimeout): ErrGRPCTimeout, ErrorDesc(ErrGRPCTimeout): ErrGRPCTimeout,
grpc.ErrorDesc(ErrGRPCTimeoutDueToLeaderFail): ErrGRPCTimeoutDueToLeaderFail, ErrorDesc(ErrGRPCTimeoutDueToLeaderFail): ErrGRPCTimeoutDueToLeaderFail,
grpc.ErrorDesc(ErrGRPCTimeoutDueToConnectionLost): ErrGRPCTimeoutDueToConnectionLost, ErrorDesc(ErrGRPCTimeoutDueToConnectionLost): ErrGRPCTimeoutDueToConnectionLost,
grpc.ErrorDesc(ErrGRPCUnhealthy): ErrGRPCUnhealthy, ErrorDesc(ErrGRPCUnhealthy): ErrGRPCUnhealthy,
grpc.ErrorDesc(ErrGRPCCorrupt): ErrGRPCCorrupt, ErrorDesc(ErrGRPCCorrupt): ErrGRPCCorrupt,
} }
)
// client-side error // client-side error
var (
ErrEmptyKey = Error(ErrGRPCEmptyKey) ErrEmptyKey = Error(ErrGRPCEmptyKey)
ErrKeyNotFound = Error(ErrGRPCKeyNotFound) ErrKeyNotFound = Error(ErrGRPCKeyNotFound)
ErrValueProvided = Error(ErrGRPCValueProvided) ErrValueProvided = Error(ErrGRPCValueProvided)
@ -188,9 +190,23 @@ func Error(err error) error {
if err == nil { if err == nil {
return nil return nil
} }
verr, ok := errStringToError[grpc.ErrorDesc(err)] verr, ok := errStringToError[ErrorDesc(err)]
if !ok { // not gRPC error if !ok { // not gRPC error
return err return err
} }
return EtcdError{code: grpc.Code(verr), desc: grpc.ErrorDesc(verr)} ev, ok := status.FromError(verr)
var desc string
if ok {
desc = ev.Message()
} else {
desc = verr.Error()
}
return EtcdError{code: ev.Code(), desc: desc}
}
func ErrorDesc(err error) string {
if s, ok := status.FromError(err); ok {
return s.Message()
}
return err.Error()
} }

View File

@ -17,26 +17,28 @@ package rpctypes
import ( import (
"testing" "testing"
"google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
func TestConvert(t *testing.T) { func TestConvert(t *testing.T) {
e1 := grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided") e1 := status.New(codes.InvalidArgument, "etcdserver: key is not provided").Err()
e2 := ErrGRPCEmptyKey e2 := ErrGRPCEmptyKey
e3 := ErrEmptyKey e3 := ErrEmptyKey
if e1.Error() != e2.Error() { if e1.Error() != e2.Error() {
t.Fatalf("expected %q == %q", e1.Error(), e2.Error()) t.Fatalf("expected %q == %q", e1.Error(), e2.Error())
} }
if grpc.Code(e1) != e3.(EtcdError).Code() { ev1, _ := status.FromError(e1)
t.Fatalf("expected them to be equal, got %v / %v", grpc.Code(e1), e3.(EtcdError).Code()) if ev1.Code() != e3.(EtcdError).Code() {
t.Fatalf("expected them to be equal, got %v / %v", ev1.Code(), e3.(EtcdError).Code())
} }
if e1.Error() == e3.Error() { if e1.Error() == e3.Error() {
t.Fatalf("expected %q != %q", e1.Error(), e3.Error()) t.Fatalf("expected %q != %q", e1.Error(), e3.Error())
} }
if grpc.Code(e2) != e3.(EtcdError).Code() { ev2, _ := status.FromError(e2)
t.Fatalf("expected them to be equal, got %v / %v", grpc.Code(e2), e3.(EtcdError).Code()) if ev2.Code() != e3.(EtcdError).Code() {
t.Fatalf("expected them to be equal, got %v / %v", ev2.Code(), e3.(EtcdError).Code())
} }
} }

View File

@ -20,6 +20,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/pkg/testutil" "github.com/coreos/etcd/pkg/testutil"
@ -79,9 +80,11 @@ func TestV3KVInflightRangeRequests(t *testing.T) {
go func() { go func() {
defer wg.Done() defer wg.Done()
_, err := kvc.Range(ctx, &pb.RangeRequest{Key: []byte("foo"), Serializable: true}, grpc.FailFast(false)) _, err := kvc.Range(ctx, &pb.RangeRequest{Key: []byte("foo"), Serializable: true}, grpc.FailFast(false))
if err != nil && grpc.ErrorDesc(err) != context.Canceled.Error() { if err != nil {
if err != nil && rpctypes.ErrorDesc(err) != context.Canceled.Error() {
t.Fatalf("inflight request should be canceld with %v, got %v", context.Canceled, err) t.Fatalf("inflight request should be canceld with %v, got %v", context.Canceled, err)
} }
}
}() }()
} }

View File

@ -1778,7 +1778,7 @@ func TestGRPCRequireLeader(t *testing.T) {
md := metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader) md := metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader)
ctx := metadata.NewOutgoingContext(context.Background(), md) ctx := metadata.NewOutgoingContext(context.Background(), md)
reqput := &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")} reqput := &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")}
if _, err := toGRPC(client).KV.Put(ctx, reqput); grpc.ErrorDesc(err) != rpctypes.ErrNoLeader.Error() { if _, err := toGRPC(client).KV.Put(ctx, reqput); rpctypes.ErrorDesc(err) != rpctypes.ErrNoLeader.Error() {
t.Errorf("err = %v, want %v", err, rpctypes.ErrNoLeader) t.Errorf("err = %v, want %v", err, rpctypes.ErrNoLeader)
} }
} }
@ -1809,7 +1809,7 @@ func TestGRPCStreamRequireLeader(t *testing.T) {
// existing stream should be rejected // existing stream should be rejected
_, err = wStream.Recv() _, err = wStream.Recv()
if grpc.ErrorDesc(err) != rpctypes.ErrNoLeader.Error() { if rpctypes.ErrorDesc(err) != rpctypes.ErrNoLeader.Error() {
t.Errorf("err = %v, want %v", err, rpctypes.ErrNoLeader) t.Errorf("err = %v, want %v", err, rpctypes.ErrNoLeader)
} }
@ -1819,7 +1819,7 @@ func TestGRPCStreamRequireLeader(t *testing.T) {
t.Fatalf("wAPI.Watch error: %v", err) t.Fatalf("wAPI.Watch error: %v", err)
} }
_, err = wStream.Recv() _, err = wStream.Recv()
if grpc.ErrorDesc(err) != rpctypes.ErrNoLeader.Error() { if rpctypes.ErrorDesc(err) != rpctypes.ErrNoLeader.Error() {
t.Errorf("err = %v, want %v", err, rpctypes.ErrNoLeader) t.Errorf("err = %v, want %v", err, rpctypes.ErrNoLeader)
} }

View File

@ -25,7 +25,6 @@ import (
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/mvcc/mvccpb"
"github.com/coreos/etcd/pkg/testutil" "github.com/coreos/etcd/pkg/testutil"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
) )
@ -560,7 +559,7 @@ func TestV3LeaseRequireLeader(t *testing.T) {
if err == nil { if err == nil {
t.Fatalf("got response %+v, expected error", resp) t.Fatalf("got response %+v, expected error", resp)
} }
if grpc.ErrorDesc(err) != rpctypes.ErrNoLeader.Error() { if rpctypes.ErrorDesc(err) != rpctypes.ErrNoLeader.Error() {
t.Errorf("err = %v, want %v", err, rpctypes.ErrNoLeader) t.Errorf("err = %v, want %v", err, rpctypes.ErrNoLeader)
} }
}() }()

View File

@ -22,10 +22,10 @@ import (
"github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/clientv3/naming" "github.com/coreos/etcd/clientv3/naming"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/time/rate" "golang.org/x/time/rate"
"google.golang.org/grpc"
gnaming "google.golang.org/grpc/naming" gnaming "google.golang.org/grpc/naming"
) )
@ -89,7 +89,7 @@ func (cp *clusterProxy) monitor(wa gnaming.Watcher) {
ups, err := wa.Next() ups, err := wa.Next()
if err != nil { if err != nil {
plog.Warningf("clusterProxy watcher error (%v)", err) plog.Warningf("clusterProxy watcher error (%v)", err)
if grpc.ErrorDesc(err) == naming.ErrWatcherClosed.Error() { if rpctypes.ErrorDesc(err) == naming.ErrWatcherClosed.Error() {
return return
} }
} }

View File

@ -20,6 +20,7 @@ import (
"sync" "sync"
"github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
"golang.org/x/time/rate" "golang.org/x/time/rate"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -68,7 +69,7 @@ func (l *leader) recvLoop() {
} }
if cresp.Err() != nil { if cresp.Err() != nil {
l.loseLeader() l.loseLeader()
if grpc.ErrorDesc(cresp.Err()) == grpc.ErrClientConnClosing.Error() { if rpctypes.ErrorDesc(cresp.Err()) == grpc.ErrClientConnClosing.Error() {
close(l.disconnc) close(l.disconnc)
return return
} }

View File

@ -24,8 +24,8 @@ import (
"github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
var ( var (
@ -68,7 +68,8 @@ func runLeaseRenewerFunc(cmd *cobra.Command, args []string) {
for { for {
lk, err = c.Lease.KeepAliveOnce(ctx, l.ID) lk, err = c.Lease.KeepAliveOnce(ctx, l.ID)
if grpc.Code(err) == codes.NotFound { ev, _ := status.FromError(err)
if ev.Code() == codes.NotFound {
if time.Since(expire) < 0 { if time.Since(expire) < 0 {
log.Fatalf("bad renew! exceeded: %v", time.Since(expire)) log.Fatalf("bad renew! exceeded: %v", time.Since(expire))
for { for {

View File

@ -106,7 +106,7 @@ func (s *keyStresser) run(ctx context.Context) {
continue continue
} }
switch grpc.ErrorDesc(err) { switch rpctypes.ErrorDesc(err) {
case context.DeadlineExceeded.Error(): case context.DeadlineExceeded.Error():
// This retries when request is triggered at the same time as // This retries when request is triggered at the same time as
// leader failure. When we terminate the leader, the request to // leader failure. When we terminate the leader, the request to