Naveen Sampath | 04696f7 | 2022-06-13 15:19:14 +0530 | [diff] [blame^] | 1 | // Copyright 2015 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 rpctypes |
| 16 | |
| 17 | import ( |
| 18 | "google.golang.org/grpc/codes" |
| 19 | "google.golang.org/grpc/status" |
| 20 | ) |
| 21 | |
| 22 | // server-side error |
| 23 | var ( |
| 24 | ErrGRPCEmptyKey = status.New(codes.InvalidArgument, "etcdserver: key is not provided").Err() |
| 25 | ErrGRPCKeyNotFound = status.New(codes.InvalidArgument, "etcdserver: key not found").Err() |
| 26 | ErrGRPCValueProvided = status.New(codes.InvalidArgument, "etcdserver: value is provided").Err() |
| 27 | ErrGRPCLeaseProvided = status.New(codes.InvalidArgument, "etcdserver: lease is provided").Err() |
| 28 | ErrGRPCTooManyOps = status.New(codes.InvalidArgument, "etcdserver: too many operations in txn request").Err() |
| 29 | ErrGRPCDuplicateKey = status.New(codes.InvalidArgument, "etcdserver: duplicate key given in txn request").Err() |
| 30 | ErrGRPCCompacted = status.New(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted").Err() |
| 31 | ErrGRPCFutureRev = status.New(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision").Err() |
| 32 | ErrGRPCNoSpace = status.New(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded").Err() |
| 33 | |
| 34 | ErrGRPCLeaseNotFound = status.New(codes.NotFound, "etcdserver: requested lease not found").Err() |
| 35 | ErrGRPCLeaseExist = status.New(codes.FailedPrecondition, "etcdserver: lease already exists").Err() |
| 36 | ErrGRPCLeaseTTLTooLarge = status.New(codes.OutOfRange, "etcdserver: too large lease TTL").Err() |
| 37 | |
| 38 | ErrGRPCMemberExist = status.New(codes.FailedPrecondition, "etcdserver: member ID already exist").Err() |
| 39 | ErrGRPCPeerURLExist = status.New(codes.FailedPrecondition, "etcdserver: Peer URLs already exists").Err() |
| 40 | ErrGRPCMemberNotEnoughStarted = status.New(codes.FailedPrecondition, "etcdserver: re-configuration failed due to not enough started members").Err() |
| 41 | ErrGRPCMemberBadURLs = status.New(codes.InvalidArgument, "etcdserver: given member URLs are invalid").Err() |
| 42 | ErrGRPCMemberNotFound = status.New(codes.NotFound, "etcdserver: member not found").Err() |
| 43 | |
| 44 | ErrGRPCRequestTooLarge = status.New(codes.InvalidArgument, "etcdserver: request is too large").Err() |
| 45 | ErrGRPCRequestTooManyRequests = status.New(codes.ResourceExhausted, "etcdserver: too many requests").Err() |
| 46 | |
| 47 | ErrGRPCRootUserNotExist = status.New(codes.FailedPrecondition, "etcdserver: root user does not exist").Err() |
| 48 | ErrGRPCRootRoleNotExist = status.New(codes.FailedPrecondition, "etcdserver: root user does not have root role").Err() |
| 49 | ErrGRPCUserAlreadyExist = status.New(codes.FailedPrecondition, "etcdserver: user name already exists").Err() |
| 50 | ErrGRPCUserEmpty = status.New(codes.InvalidArgument, "etcdserver: user name is empty").Err() |
| 51 | ErrGRPCUserNotFound = status.New(codes.FailedPrecondition, "etcdserver: user name not found").Err() |
| 52 | ErrGRPCRoleAlreadyExist = status.New(codes.FailedPrecondition, "etcdserver: role name already exists").Err() |
| 53 | ErrGRPCRoleNotFound = status.New(codes.FailedPrecondition, "etcdserver: role name not found").Err() |
| 54 | ErrGRPCAuthFailed = status.New(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password").Err() |
| 55 | ErrGRPCPermissionDenied = status.New(codes.PermissionDenied, "etcdserver: permission denied").Err() |
| 56 | ErrGRPCRoleNotGranted = status.New(codes.FailedPrecondition, "etcdserver: role is not granted to the user").Err() |
| 57 | ErrGRPCPermissionNotGranted = status.New(codes.FailedPrecondition, "etcdserver: permission is not granted to the role").Err() |
| 58 | ErrGRPCAuthNotEnabled = status.New(codes.FailedPrecondition, "etcdserver: authentication is not enabled").Err() |
| 59 | ErrGRPCInvalidAuthToken = status.New(codes.Unauthenticated, "etcdserver: invalid auth token").Err() |
| 60 | ErrGRPCInvalidAuthMgmt = status.New(codes.InvalidArgument, "etcdserver: invalid auth management").Err() |
| 61 | |
| 62 | ErrGRPCNoLeader = status.New(codes.Unavailable, "etcdserver: no leader").Err() |
| 63 | ErrGRPCNotLeader = status.New(codes.FailedPrecondition, "etcdserver: not leader").Err() |
| 64 | ErrGRPCLeaderChanged = status.New(codes.Unavailable, "etcdserver: leader changed").Err() |
| 65 | ErrGRPCNotCapable = status.New(codes.Unavailable, "etcdserver: not capable").Err() |
| 66 | ErrGRPCStopped = status.New(codes.Unavailable, "etcdserver: server stopped").Err() |
| 67 | ErrGRPCTimeout = status.New(codes.Unavailable, "etcdserver: request timed out").Err() |
| 68 | ErrGRPCTimeoutDueToLeaderFail = status.New(codes.Unavailable, "etcdserver: request timed out, possibly due to previous leader failure").Err() |
| 69 | ErrGRPCTimeoutDueToConnectionLost = status.New(codes.Unavailable, "etcdserver: request timed out, possibly due to connection lost").Err() |
| 70 | ErrGRPCUnhealthy = status.New(codes.Unavailable, "etcdserver: unhealthy cluster").Err() |
| 71 | ErrGRPCCorrupt = status.New(codes.DataLoss, "etcdserver: corrupt cluster").Err() |
| 72 | |
| 73 | errStringToError = map[string]error{ |
| 74 | ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey, |
| 75 | ErrorDesc(ErrGRPCKeyNotFound): ErrGRPCKeyNotFound, |
| 76 | ErrorDesc(ErrGRPCValueProvided): ErrGRPCValueProvided, |
| 77 | ErrorDesc(ErrGRPCLeaseProvided): ErrGRPCLeaseProvided, |
| 78 | |
| 79 | ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps, |
| 80 | ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey, |
| 81 | ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted, |
| 82 | ErrorDesc(ErrGRPCFutureRev): ErrGRPCFutureRev, |
| 83 | ErrorDesc(ErrGRPCNoSpace): ErrGRPCNoSpace, |
| 84 | |
| 85 | ErrorDesc(ErrGRPCLeaseNotFound): ErrGRPCLeaseNotFound, |
| 86 | ErrorDesc(ErrGRPCLeaseExist): ErrGRPCLeaseExist, |
| 87 | ErrorDesc(ErrGRPCLeaseTTLTooLarge): ErrGRPCLeaseTTLTooLarge, |
| 88 | |
| 89 | ErrorDesc(ErrGRPCMemberExist): ErrGRPCMemberExist, |
| 90 | ErrorDesc(ErrGRPCPeerURLExist): ErrGRPCPeerURLExist, |
| 91 | ErrorDesc(ErrGRPCMemberNotEnoughStarted): ErrGRPCMemberNotEnoughStarted, |
| 92 | ErrorDesc(ErrGRPCMemberBadURLs): ErrGRPCMemberBadURLs, |
| 93 | ErrorDesc(ErrGRPCMemberNotFound): ErrGRPCMemberNotFound, |
| 94 | |
| 95 | ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge, |
| 96 | ErrorDesc(ErrGRPCRequestTooManyRequests): ErrGRPCRequestTooManyRequests, |
| 97 | |
| 98 | ErrorDesc(ErrGRPCRootUserNotExist): ErrGRPCRootUserNotExist, |
| 99 | ErrorDesc(ErrGRPCRootRoleNotExist): ErrGRPCRootRoleNotExist, |
| 100 | ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist, |
| 101 | ErrorDesc(ErrGRPCUserEmpty): ErrGRPCUserEmpty, |
| 102 | ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound, |
| 103 | ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist, |
| 104 | ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound, |
| 105 | ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed, |
| 106 | ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied, |
| 107 | ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted, |
| 108 | ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted, |
| 109 | ErrorDesc(ErrGRPCAuthNotEnabled): ErrGRPCAuthNotEnabled, |
| 110 | ErrorDesc(ErrGRPCInvalidAuthToken): ErrGRPCInvalidAuthToken, |
| 111 | ErrorDesc(ErrGRPCInvalidAuthMgmt): ErrGRPCInvalidAuthMgmt, |
| 112 | |
| 113 | ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader, |
| 114 | ErrorDesc(ErrGRPCNotLeader): ErrGRPCNotLeader, |
| 115 | ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable, |
| 116 | ErrorDesc(ErrGRPCStopped): ErrGRPCStopped, |
| 117 | ErrorDesc(ErrGRPCTimeout): ErrGRPCTimeout, |
| 118 | ErrorDesc(ErrGRPCTimeoutDueToLeaderFail): ErrGRPCTimeoutDueToLeaderFail, |
| 119 | ErrorDesc(ErrGRPCTimeoutDueToConnectionLost): ErrGRPCTimeoutDueToConnectionLost, |
| 120 | ErrorDesc(ErrGRPCUnhealthy): ErrGRPCUnhealthy, |
| 121 | ErrorDesc(ErrGRPCCorrupt): ErrGRPCCorrupt, |
| 122 | } |
| 123 | ) |
| 124 | |
| 125 | // client-side error |
| 126 | var ( |
| 127 | ErrEmptyKey = Error(ErrGRPCEmptyKey) |
| 128 | ErrKeyNotFound = Error(ErrGRPCKeyNotFound) |
| 129 | ErrValueProvided = Error(ErrGRPCValueProvided) |
| 130 | ErrLeaseProvided = Error(ErrGRPCLeaseProvided) |
| 131 | ErrTooManyOps = Error(ErrGRPCTooManyOps) |
| 132 | ErrDuplicateKey = Error(ErrGRPCDuplicateKey) |
| 133 | ErrCompacted = Error(ErrGRPCCompacted) |
| 134 | ErrFutureRev = Error(ErrGRPCFutureRev) |
| 135 | ErrNoSpace = Error(ErrGRPCNoSpace) |
| 136 | |
| 137 | ErrLeaseNotFound = Error(ErrGRPCLeaseNotFound) |
| 138 | ErrLeaseExist = Error(ErrGRPCLeaseExist) |
| 139 | ErrLeaseTTLTooLarge = Error(ErrGRPCLeaseTTLTooLarge) |
| 140 | |
| 141 | ErrMemberExist = Error(ErrGRPCMemberExist) |
| 142 | ErrPeerURLExist = Error(ErrGRPCPeerURLExist) |
| 143 | ErrMemberNotEnoughStarted = Error(ErrGRPCMemberNotEnoughStarted) |
| 144 | ErrMemberBadURLs = Error(ErrGRPCMemberBadURLs) |
| 145 | ErrMemberNotFound = Error(ErrGRPCMemberNotFound) |
| 146 | |
| 147 | ErrRequestTooLarge = Error(ErrGRPCRequestTooLarge) |
| 148 | ErrTooManyRequests = Error(ErrGRPCRequestTooManyRequests) |
| 149 | |
| 150 | ErrRootUserNotExist = Error(ErrGRPCRootUserNotExist) |
| 151 | ErrRootRoleNotExist = Error(ErrGRPCRootRoleNotExist) |
| 152 | ErrUserAlreadyExist = Error(ErrGRPCUserAlreadyExist) |
| 153 | ErrUserEmpty = Error(ErrGRPCUserEmpty) |
| 154 | ErrUserNotFound = Error(ErrGRPCUserNotFound) |
| 155 | ErrRoleAlreadyExist = Error(ErrGRPCRoleAlreadyExist) |
| 156 | ErrRoleNotFound = Error(ErrGRPCRoleNotFound) |
| 157 | ErrAuthFailed = Error(ErrGRPCAuthFailed) |
| 158 | ErrPermissionDenied = Error(ErrGRPCPermissionDenied) |
| 159 | ErrRoleNotGranted = Error(ErrGRPCRoleNotGranted) |
| 160 | ErrPermissionNotGranted = Error(ErrGRPCPermissionNotGranted) |
| 161 | ErrAuthNotEnabled = Error(ErrGRPCAuthNotEnabled) |
| 162 | ErrInvalidAuthToken = Error(ErrGRPCInvalidAuthToken) |
| 163 | ErrInvalidAuthMgmt = Error(ErrGRPCInvalidAuthMgmt) |
| 164 | |
| 165 | ErrNoLeader = Error(ErrGRPCNoLeader) |
| 166 | ErrNotLeader = Error(ErrGRPCNotLeader) |
| 167 | ErrLeaderChanged = Error(ErrGRPCLeaderChanged) |
| 168 | ErrNotCapable = Error(ErrGRPCNotCapable) |
| 169 | ErrStopped = Error(ErrGRPCStopped) |
| 170 | ErrTimeout = Error(ErrGRPCTimeout) |
| 171 | ErrTimeoutDueToLeaderFail = Error(ErrGRPCTimeoutDueToLeaderFail) |
| 172 | ErrTimeoutDueToConnectionLost = Error(ErrGRPCTimeoutDueToConnectionLost) |
| 173 | ErrUnhealthy = Error(ErrGRPCUnhealthy) |
| 174 | ErrCorrupt = Error(ErrGRPCCorrupt) |
| 175 | ) |
| 176 | |
| 177 | // EtcdError defines gRPC server errors. |
| 178 | // (https://github.com/grpc/grpc-go/blob/master/rpc_util.go#L319-L323) |
| 179 | type EtcdError struct { |
| 180 | code codes.Code |
| 181 | desc string |
| 182 | } |
| 183 | |
| 184 | // Code returns grpc/codes.Code. |
| 185 | // TODO: define clientv3/codes.Code. |
| 186 | func (e EtcdError) Code() codes.Code { |
| 187 | return e.code |
| 188 | } |
| 189 | |
| 190 | func (e EtcdError) Error() string { |
| 191 | return e.desc |
| 192 | } |
| 193 | |
| 194 | func Error(err error) error { |
| 195 | if err == nil { |
| 196 | return nil |
| 197 | } |
| 198 | verr, ok := errStringToError[ErrorDesc(err)] |
| 199 | if !ok { // not gRPC error |
| 200 | return err |
| 201 | } |
| 202 | ev, ok := status.FromError(verr) |
| 203 | var desc string |
| 204 | if ok { |
| 205 | desc = ev.Message() |
| 206 | } else { |
| 207 | desc = verr.Error() |
| 208 | } |
| 209 | return EtcdError{code: ev.Code(), desc: desc} |
| 210 | } |
| 211 | |
| 212 | func ErrorDesc(err error) string { |
| 213 | if s, ok := status.FromError(err); ok { |
| 214 | return s.Message() |
| 215 | } |
| 216 | return err.Error() |
| 217 | } |