go.etcd.io/etcd@v3.3.27+incompatible/etcdserver/api/v3rpc/util.go (about) 1 // Copyright 2016 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package v3rpc 16 17 import ( 18 "context" 19 "strings" 20 21 "github.com/coreos/etcd/auth" 22 "github.com/coreos/etcd/etcdserver" 23 "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" 24 "github.com/coreos/etcd/etcdserver/membership" 25 "github.com/coreos/etcd/lease" 26 "github.com/coreos/etcd/mvcc" 27 28 "google.golang.org/grpc/codes" 29 "google.golang.org/grpc/status" 30 ) 31 32 var toGRPCErrorMap = map[error]error{ 33 membership.ErrIDRemoved: rpctypes.ErrGRPCMemberNotFound, 34 membership.ErrIDNotFound: rpctypes.ErrGRPCMemberNotFound, 35 membership.ErrIDExists: rpctypes.ErrGRPCMemberExist, 36 membership.ErrPeerURLexists: rpctypes.ErrGRPCPeerURLExist, 37 etcdserver.ErrNotEnoughStartedMembers: rpctypes.ErrMemberNotEnoughStarted, 38 39 mvcc.ErrCompacted: rpctypes.ErrGRPCCompacted, 40 mvcc.ErrFutureRev: rpctypes.ErrGRPCFutureRev, 41 etcdserver.ErrRequestTooLarge: rpctypes.ErrGRPCRequestTooLarge, 42 etcdserver.ErrNoSpace: rpctypes.ErrGRPCNoSpace, 43 etcdserver.ErrTooManyRequests: rpctypes.ErrTooManyRequests, 44 45 etcdserver.ErrNoLeader: rpctypes.ErrGRPCNoLeader, 46 etcdserver.ErrNotLeader: rpctypes.ErrGRPCNotLeader, 47 etcdserver.ErrLeaderChanged: rpctypes.ErrGRPCLeaderChanged, 48 etcdserver.ErrStopped: rpctypes.ErrGRPCStopped, 49 etcdserver.ErrTimeout: rpctypes.ErrGRPCTimeout, 50 etcdserver.ErrTimeoutDueToLeaderFail: rpctypes.ErrGRPCTimeoutDueToLeaderFail, 51 etcdserver.ErrTimeoutDueToConnectionLost: rpctypes.ErrGRPCTimeoutDueToConnectionLost, 52 etcdserver.ErrUnhealthy: rpctypes.ErrGRPCUnhealthy, 53 etcdserver.ErrKeyNotFound: rpctypes.ErrGRPCKeyNotFound, 54 etcdserver.ErrCorrupt: rpctypes.ErrGRPCCorrupt, 55 56 lease.ErrLeaseNotFound: rpctypes.ErrGRPCLeaseNotFound, 57 lease.ErrLeaseExists: rpctypes.ErrGRPCLeaseExist, 58 lease.ErrLeaseTTLTooLarge: rpctypes.ErrGRPCLeaseTTLTooLarge, 59 60 auth.ErrRootUserNotExist: rpctypes.ErrGRPCRootUserNotExist, 61 auth.ErrRootRoleNotExist: rpctypes.ErrGRPCRootRoleNotExist, 62 auth.ErrUserAlreadyExist: rpctypes.ErrGRPCUserAlreadyExist, 63 auth.ErrUserEmpty: rpctypes.ErrGRPCUserEmpty, 64 auth.ErrUserNotFound: rpctypes.ErrGRPCUserNotFound, 65 auth.ErrRoleAlreadyExist: rpctypes.ErrGRPCRoleAlreadyExist, 66 auth.ErrRoleNotFound: rpctypes.ErrGRPCRoleNotFound, 67 auth.ErrAuthFailed: rpctypes.ErrGRPCAuthFailed, 68 auth.ErrPermissionDenied: rpctypes.ErrGRPCPermissionDenied, 69 auth.ErrRoleNotGranted: rpctypes.ErrGRPCRoleNotGranted, 70 auth.ErrPermissionNotGranted: rpctypes.ErrGRPCPermissionNotGranted, 71 auth.ErrAuthNotEnabled: rpctypes.ErrGRPCAuthNotEnabled, 72 auth.ErrInvalidAuthToken: rpctypes.ErrGRPCInvalidAuthToken, 73 auth.ErrInvalidAuthMgmt: rpctypes.ErrGRPCInvalidAuthMgmt, 74 } 75 76 func togRPCError(err error) error { 77 // let gRPC server convert to codes.Canceled, codes.DeadlineExceeded 78 if err == context.Canceled || err == context.DeadlineExceeded { 79 return err 80 } 81 grpcErr, ok := toGRPCErrorMap[err] 82 if !ok { 83 return status.Error(codes.Unknown, err.Error()) 84 } 85 return grpcErr 86 } 87 88 func isClientCtxErr(ctxErr error, err error) bool { 89 if ctxErr != nil { 90 return true 91 } 92 93 ev, ok := status.FromError(err) 94 if !ok { 95 return false 96 } 97 98 switch ev.Code() { 99 case codes.Canceled, codes.DeadlineExceeded: 100 // client-side context cancel or deadline exceeded 101 // "rpc error: code = Canceled desc = context canceled" 102 // "rpc error: code = DeadlineExceeded desc = context deadline exceeded" 103 return true 104 case codes.Unavailable: 105 msg := ev.Message() 106 // client-side context cancel or deadline exceeded with TLS ("http2.errClientDisconnected") 107 // "rpc error: code = Unavailable desc = client disconnected" 108 if msg == "client disconnected" { 109 return true 110 } 111 // "grpc/transport.ClientTransport.CloseStream" on canceled streams 112 // "rpc error: code = Unavailable desc = stream error: stream ID 21; CANCEL") 113 if strings.HasPrefix(msg, "stream error: ") && strings.HasSuffix(msg, "; CANCEL") { 114 return true 115 } 116 } 117 return false 118 }