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
15package rpctypes
16
17import (
18	"google.golang.org/grpc/codes"
19	"google.golang.org/grpc/status"
20)
21
22// server-side error
23var (
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(ErrGRPCLeaderChanged):              ErrGRPCLeaderChanged,
116		ErrorDesc(ErrGRPCNotCapable):                 ErrGRPCNotCapable,
117		ErrorDesc(ErrGRPCStopped):                    ErrGRPCStopped,
118		ErrorDesc(ErrGRPCTimeout):                    ErrGRPCTimeout,
119		ErrorDesc(ErrGRPCTimeoutDueToLeaderFail):     ErrGRPCTimeoutDueToLeaderFail,
120		ErrorDesc(ErrGRPCTimeoutDueToConnectionLost): ErrGRPCTimeoutDueToConnectionLost,
121		ErrorDesc(ErrGRPCUnhealthy):                  ErrGRPCUnhealthy,
122		ErrorDesc(ErrGRPCCorrupt):                    ErrGRPCCorrupt,
123	}
124)
125
126// client-side error
127var (
128	ErrEmptyKey      = Error(ErrGRPCEmptyKey)
129	ErrKeyNotFound   = Error(ErrGRPCKeyNotFound)
130	ErrValueProvided = Error(ErrGRPCValueProvided)
131	ErrLeaseProvided = Error(ErrGRPCLeaseProvided)
132	ErrTooManyOps    = Error(ErrGRPCTooManyOps)
133	ErrDuplicateKey  = Error(ErrGRPCDuplicateKey)
134	ErrCompacted     = Error(ErrGRPCCompacted)
135	ErrFutureRev     = Error(ErrGRPCFutureRev)
136	ErrNoSpace       = Error(ErrGRPCNoSpace)
137
138	ErrLeaseNotFound    = Error(ErrGRPCLeaseNotFound)
139	ErrLeaseExist       = Error(ErrGRPCLeaseExist)
140	ErrLeaseTTLTooLarge = Error(ErrGRPCLeaseTTLTooLarge)
141
142	ErrMemberExist            = Error(ErrGRPCMemberExist)
143	ErrPeerURLExist           = Error(ErrGRPCPeerURLExist)
144	ErrMemberNotEnoughStarted = Error(ErrGRPCMemberNotEnoughStarted)
145	ErrMemberBadURLs          = Error(ErrGRPCMemberBadURLs)
146	ErrMemberNotFound         = Error(ErrGRPCMemberNotFound)
147
148	ErrRequestTooLarge = Error(ErrGRPCRequestTooLarge)
149	ErrTooManyRequests = Error(ErrGRPCRequestTooManyRequests)
150
151	ErrRootUserNotExist     = Error(ErrGRPCRootUserNotExist)
152	ErrRootRoleNotExist     = Error(ErrGRPCRootRoleNotExist)
153	ErrUserAlreadyExist     = Error(ErrGRPCUserAlreadyExist)
154	ErrUserEmpty            = Error(ErrGRPCUserEmpty)
155	ErrUserNotFound         = Error(ErrGRPCUserNotFound)
156	ErrRoleAlreadyExist     = Error(ErrGRPCRoleAlreadyExist)
157	ErrRoleNotFound         = Error(ErrGRPCRoleNotFound)
158	ErrAuthFailed           = Error(ErrGRPCAuthFailed)
159	ErrPermissionDenied     = Error(ErrGRPCPermissionDenied)
160	ErrRoleNotGranted       = Error(ErrGRPCRoleNotGranted)
161	ErrPermissionNotGranted = Error(ErrGRPCPermissionNotGranted)
162	ErrAuthNotEnabled       = Error(ErrGRPCAuthNotEnabled)
163	ErrInvalidAuthToken     = Error(ErrGRPCInvalidAuthToken)
164	ErrInvalidAuthMgmt      = Error(ErrGRPCInvalidAuthMgmt)
165
166	ErrNoLeader                   = Error(ErrGRPCNoLeader)
167	ErrNotLeader                  = Error(ErrGRPCNotLeader)
168	ErrLeaderChanged              = Error(ErrGRPCLeaderChanged)
169	ErrNotCapable                 = Error(ErrGRPCNotCapable)
170	ErrStopped                    = Error(ErrGRPCStopped)
171	ErrTimeout                    = Error(ErrGRPCTimeout)
172	ErrTimeoutDueToLeaderFail     = Error(ErrGRPCTimeoutDueToLeaderFail)
173	ErrTimeoutDueToConnectionLost = Error(ErrGRPCTimeoutDueToConnectionLost)
174	ErrUnhealthy                  = Error(ErrGRPCUnhealthy)
175	ErrCorrupt                    = Error(ErrGRPCCorrupt)
176)
177
178// EtcdError defines gRPC server errors.
179// (https://github.com/grpc/grpc-go/blob/master/rpc_util.go#L319-L323)
180type EtcdError struct {
181	code codes.Code
182	desc string
183}
184
185// Code returns grpc/codes.Code.
186// TODO: define clientv3/codes.Code.
187func (e EtcdError) Code() codes.Code {
188	return e.code
189}
190
191func (e EtcdError) Error() string {
192	return e.desc
193}
194
195func Error(err error) error {
196	if err == nil {
197		return nil
198	}
199	verr, ok := errStringToError[ErrorDesc(err)]
200	if !ok { // not gRPC error
201		return err
202	}
203	ev, ok := status.FromError(verr)
204	var desc string
205	if ok {
206		desc = ev.Message()
207	} else {
208		desc = verr.Error()
209	}
210	return EtcdError{code: ev.Code(), desc: desc}
211}
212
213func ErrorDesc(err error) string {
214	if s, ok := status.FromError(err); ok {
215		return s.Message()
216	}
217	return err.Error()
218}
219