1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 * Copyright 2017 Couchbase, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 #pragma once
18
19 #include <platform/dynamic.h>
20
21 #include <cstdint>
22 #include <system_error>
23 #include <string>
24
25 namespace cb {
26 namespace mcbp {
27 /**
28 * Definition of the valid response status numbers.
29 *
30 * A well written client should be "future proof" by handling new
31 * error codes to be defined. Note that new error codes means that
32 * the requested operation wasn't performed.
33 */
34 enum class Status : uint16_t {
35 /** The operation completed successfully */
36 Success = 0x00,
37 /** The key does not exists */
38 KeyEnoent = 0x01,
39 /** The key exists in the cluster (with another CAS value) */
40 KeyEexists = 0x02,
41 /** The document exceeds the maximum size */
42 E2big = 0x03,
43 /** Invalid request */
44 Einval = 0x04,
45 /** The document was not stored for some reason. This is
46 * currently a "catch all" for number or error situations, and
47 * should be split into multiple error codes. */
48 NotStored = 0x05,
49 /** Non-numeric server-side value for incr or decr */
50 DeltaBadval = 0x06,
51 /** The server is not responsible for the requested vbucket */
52 NotMyVbucket = 0x07,
53 /** Not connected to a bucket */
54 NoBucket = 0x08,
55 /** The requested resource is locked */
56 Locked = 0x09,
57 /** The authentication context is stale. You should reauthenticate*/
58 AuthStale = 0x1f,
59 /** Authentication failure (invalid user/password combination,
60 * OR an internal error in the authentication library. Could
61 * be a misconfigured SASL configuration. See server logs for
62 * more information.) */
63 AuthError = 0x20,
64 /** Authentication OK so far, please continue */
65 AuthContinue = 0x21,
66 /** The requested value is outside the legal range
67 * (similar to EINVAL, but more specific) */
68 Erange = 0x22,
69 /** Roll back to an earlier version of the vbucket UUID
70 * (_currently_ only used by DCP for agreeing on selecting a
71 * starting point) */
72 Rollback = 0x23,
73 /** No access (could be opcode, value, bucket etc) */
74 Eaccess = 0x24,
75 /** The Couchbase cluster is currently initializing this
76 * node, and the Cluster manager has not yet granted all
77 * users access to the cluster. */
78 NotInitialized = 0x25,
79 /** The server have no idea what this command is for */
80 UnknownCommand = 0x81,
81 /** Not enough memory */
82 Enomem = 0x82,
83 /** The server does not support this command */
84 NotSupported = 0x83,
85 /** An internal error in the server */
86 Einternal = 0x84,
87 /** The system is currently too busy to handle the request.
88 * it is _currently_ only being used by the scrubber in
89 * default_engine to run a task there may only be one of
90 * (subsequent requests to start it would return ebusy until
91 * it's done). */
92 Ebusy = 0x85,
93 /** A temporary error condition occurred. Retrying the
94 * operation may resolve the problem. This could be that the
95 * server is in a degraded situation (like running warmup on
96 * the node), the vbucket could be in an "incorrect" state, a
97 * temporary failure from the underlying persistence layer,
98 * etc).
99 */
100 Etmpfail = 0x86,
101
102 /**
103 * There is something wrong with the syntax of the provided
104 * XATTR.
105 */
106 XattrEinval = 0x87,
107
108 /**
109 * Operation attempted with an unknown collection.
110 */
111 UnknownCollection = 0x88,
112
113 /**
114 * Operation attempted and requires that the collections manifest is set.
115 */
116 NoCollectionsManifest = 0x89,
117
118 /*
119 * Sub-document specific responses.
120 */
121
122 /** The provided path does not exist in the document. */
123 SubdocPathEnoent = 0xc0,
124
125 /** One of path components treats a non-dictionary as a dictionary, or
126 * a non-array as an array.
127 * [Arithmetic operations only] The value the path points to is not
128 * a number. */
129 SubdocPathMismatch = 0xc1,
130
131 /** The path’s syntax was incorrect. */
132 SubdocPathEinval = 0xc2,
133
134 /** The path provided is too large; either the string is too long,
135 * or it contains too many components. */
136 SubdocPathE2big = 0xc3,
137
138 /** The document has too many levels to parse. */
139 SubdocDocE2deep = 0xc4,
140
141 /** [For mutations only] The value provided will invalidate the JSON if
142 * inserted. */
143 SubdocValueCantinsert = 0xc5,
144
145 /** The existing document is not valid JSON. */
146 SubdocDocNotJson = 0xc6,
147
148 /** [For arithmetic ops] The existing number is out of the valid range
149 * for arithmetic ops (cannot be represented as an int64_t). */
150 SubdocNumErange = 0xc7,
151
152 /** [For arithmetic ops] The delta supplied is invalid. It is either
153 * 0, not an integer, or out of the int64 range */
154 SubdocDeltaEinval = 0xc8,
155
156 /** [For mutations only] The requested operation requires the path to
157 * not already exist, but it exists. */
158 SubdocPathEexists = 0xc9,
159
160 /** [For mutations only] Inserting the value would cause the document
161 * to be too deep. */
162 SubdocValueEtoodeep = 0xca,
163
164 /** [For multi-path commands only] An invalid combination of commands
165 * was specified. */
166 SubdocInvalidCombo = 0xcb,
167
168 /** [For multi-path commands only] Specified key was successfully
169 * found, but one or more path operations failed. Examine the individual
170 * lookup_result (MULTI_LOOKUP) / mutation_result (MULTI_MUTATION)
171 * structures for details. */
172 SubdocMultiPathFailure = 0xcc,
173
174 /**
175 * The operation completed successfully, but operated on a deleted
176 * document.
177 */
178 SubdocSuccessDeleted = 0xcd,
179
180 /**
181 * The combination of the subdoc flags for the xattrs doesn't make
182 * any sense
183 */
184 SubdocXattrInvalidFlagCombo = 0xce,
185
186 /**
187 * Only a single xattr key may be accessed at the same time.
188 */
189 SubdocXattrInvalidKeyCombo = 0xcf,
190
191 /**
192 * The server has no knowledge of the requested macro
193 */
194 SubdocXattrUnknownMacro = 0xd0,
195
196 /**
197 * The server has no knowledge of the requested virtual xattr
198 */
199 SubdocXattrUnknownVattr = 0xd1,
200
201 /**
202 * Virtual xattrs can't be modified
203 */
204 SubdocXattrCantModifyVattr = 0xd2,
205
206 /**
207 * [For multi-path commands only] Specified key was found as a
208 * Deleted document, but one or more path operations
209 * failed. Examine the individual lookup_result (MULTI_LOOKUP) /
210 * mutation_result (MULTI_MUTATION) structures for details.
211 */
212 SubdocMultiPathFailureDeleted = 0xd3,
213
214 /**
215 * According to the spec all xattr commands should come first,
216 * followed by the commands for the document body
217 */
218 SubdocInvalidXattrOrder = 0xd4,
219
220 /*************************************************************************/
221
222 /**
223 * Number of valid elements in the enumeration (as used by Couchbase).
224 * Note there are additional values reserved for user application below).
225 */
226 COUNT,
227
228 /**
229 * The following range of 256 error codes is reserved for end-user
230 * applications (e.g. proxies). Couchbase itself does not return them.
231 */
232 ReservedUserStart = 0xff00,
233 ReservedUserEnd = 0xffff
234 };
235
236 const std::error_category& error_category() NOEXCEPT;
237
238 class error : public std::system_error {
239 public:
error(Status ev, const std::string& what_arg)240 error(Status ev, const std::string& what_arg)
241 : system_error(int(ev), error_category(), what_arg) {
242 }
243
error(Status ev, const char* what_arg)244 error(Status ev, const char* what_arg)
245 : system_error(int(ev), error_category(), what_arg) {
246 }
247 };
248
make_error_condition(Status e)249 static inline std::error_condition make_error_condition(Status e) {
250 return std::error_condition(int(e), error_category());
251 }
252
253 /**
254 * Check if the provided status code represents success or a failure
255 *
256 * @param status the status code code to check
257 * @return true if the status code represents a successful critera
258 * false if the status code represents a failure and the payload
259 * should be replaced with the standard payload containing
260 * the error context and UUID (if set)
261 */
262 bool isStatusSuccess(Status status);
263
264 } // namespace mcbp
265 } // namespace cb
266
267 /**
268 * Get a textual representation of the given error code
269 */
270 std::string to_string(cb::mcbp::Status status);
271
272 namespace std {
273
274 template <>
275 struct is_error_condition_enum<cb::mcbp::Status> : public true_type {};
276
277 } // namespace std
278