1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2016 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 <memcached/engine_utilities_visibility.h>
20 #include <platform/platform.h>
21 
22 #include <iosfwd>
23 #include <system_error>
24 
25 #ifdef _MSC_VER
26 // We need to add the right __declspec magic to the system types
27 // to avoid msvc to spit out warnings
28 class ENGINE_UTILITIES_PUBLIC_API std::system_error;
29 #endif
30 
31 namespace cb {
32 /**
33  * The Error enum contains all of the various error codes the engines
34  * may return. They may be used together with the cb::engine_category()
35  * in std::system_error exceptions (where you can fetch the code, and the
36  * textual description for the given error).
37  */
38 enum class engine_errc {
39     /** The command executed successfully */
40     success = 0x00,
41     /** The key does not exists */
42     no_such_key = 0x01,
43     /** The key already exists */
44     key_already_exists = 0x02,
45     /** Could not allocate memory */
46     no_memory = 0x03,
47     /** The item was not stored */
48     not_stored = 0x04,
49     /** Invalid arguments */
50     invalid_arguments = 0x05,
51     /** The engine does not support this */
52     not_supported = 0x06,
53     /** This would cause the engine to block */
54     would_block = 0x07,
55     /** The data is too big for the engine */
56     too_big = 0x08,
57     /** The engine want more data if the frontend have more data available. */
58     want_more = 0x09,
59     /** Tell the server to disconnect this client */
60     disconnect = 0x0a,
61     /** Access control violations */
62     no_access = 0x0b,
63     /** < This vbucket doesn't belong to me */
64     not_my_vbucket = 0x0c,
65     /** Temporary failure, please try again later */
66     temporary_failure = 0x0d,
67     /** Value outside legal range */
68     out_of_range = 0x0e,
69     /** Roll back to a previous version */
70     rollback = 0x0f,
71     /** The connection isn't bound to an engine */
72     no_bucket = 0x10,
73     /** Can't serve the request.. busy */
74     too_busy = 0x11,
75     /** Auth data stale */
76     authentication_stale = 0x12,
77     /**
78      * The value stored in the document is incompatible with the
79      * requested operation.
80      */
81     delta_badval = 0x13,
82     /**
83      * The requested resource is locked
84      */
85     locked = 0x14,
86     /**
87      * The requested resource is locked, but the engine used to
88      * report it as a tmpfail (we need to be able to separate this
89      * in the core so that old clients can get TMPFAIL back instead
90      * of EEXISTS
91      */
92     locked_tmpfail = 0x15,
93 
94     /**
95      * The request has no collection or an unknown collection.
96      */
97     unknown_collection = 0x16,
98 
99     /**
100      * A command with a predicate has been failed because of the predicate
101      */
102     predicate_failed = 0x17,
103 
104     /**
105      * The request cannot complete until a collections manifest has been set
106      */
107     no_collections_manifest = 0x18,
108 
109     /** Generic failue. */
110     failed = 0xff
111 };
112 
113 /**
114  * Get the error category object used to map from numeric values to
115  * a textual representation of the error code.
116  *
117  * @return The one and only instance of the error object
118  */
119 ENGINE_UTILITIES_PUBLIC_API
120 const std::error_category& engine_error_category() NOEXCEPT;
121 
122 class ENGINE_UTILITIES_PUBLIC_API engine_error : public std::system_error {
123 public:
engine_error(engine_errc ev,const std::string & what_arg)124     engine_error(engine_errc ev, const std::string& what_arg)
125         : system_error(int(ev), engine_error_category(), what_arg) {}
126 
engine_error(engine_errc ev,const char * what_arg)127     engine_error(engine_errc ev, const char* what_arg)
128         : system_error(int(ev), engine_error_category(), what_arg) {}
129 };
130 
make_error_condition(engine_errc e)131 static inline std::error_condition make_error_condition(engine_errc e) {
132     return std::error_condition(int(e), engine_error_category());
133 }
134 
135 ENGINE_UTILITIES_PUBLIC_API
136 std::string to_string(engine_errc ev);
137 
138 // GoogleTest printing function.
139 ENGINE_UTILITIES_PUBLIC_API
140 void PrintTo(engine_errc ev, ::std::ostream* os);
141 
142 } // namespace cb
143 
144 // For checkeqfn
145 ENGINE_UTILITIES_PUBLIC_API
146 std::ostream& operator<<(std::ostream& os, cb::engine_errc ec);
147 
148 // For backwards compatibility with the old memcached source code we need
149 // to keep the old constants around
150 typedef enum {
151     ENGINE_SUCCESS = int(cb::engine_errc::success),
152     ENGINE_KEY_ENOENT = int(cb::engine_errc::no_such_key),
153     ENGINE_KEY_EEXISTS = int(cb::engine_errc::key_already_exists),
154     ENGINE_ENOMEM = int(cb::engine_errc::no_memory),
155     ENGINE_NOT_STORED = int(cb::engine_errc::not_stored),
156     ENGINE_EINVAL = int(cb::engine_errc::invalid_arguments),
157     ENGINE_ENOTSUP = int(cb::engine_errc::not_supported),
158     ENGINE_EWOULDBLOCK = int(cb::engine_errc::would_block),
159     ENGINE_E2BIG = int(cb::engine_errc::too_big),
160     ENGINE_WANT_MORE = int(cb::engine_errc::want_more),
161     ENGINE_DISCONNECT = int(cb::engine_errc::disconnect),
162     ENGINE_EACCESS = int(cb::engine_errc::no_access),
163     ENGINE_NOT_MY_VBUCKET = int(cb::engine_errc::not_my_vbucket),
164     ENGINE_TMPFAIL = int(cb::engine_errc::temporary_failure),
165     ENGINE_ERANGE = int(cb::engine_errc::out_of_range),
166     ENGINE_ROLLBACK = int(cb::engine_errc::rollback),
167     ENGINE_NO_BUCKET = int(cb::engine_errc::no_bucket),
168     ENGINE_EBUSY = int(cb::engine_errc::too_busy),
169     ENGINE_AUTH_STALE = int(cb::engine_errc::authentication_stale),
170     ENGINE_DELTA_BADVAL = int(cb::engine_errc::delta_badval),
171     ENGINE_LOCKED = int(cb::engine_errc::locked),
172     ENGINE_LOCKED_TMPFAIL = int(cb::engine_errc::locked_tmpfail),
173     ENGINE_UNKNOWN_COLLECTION = int(cb::engine_errc::unknown_collection),
174     ENGINE_FAILED = int(cb::engine_errc::failed),
175     ENGINE_PREDICATE_FAILED = int(cb::engine_errc::predicate_failed)
176 } ENGINE_ERROR_CODE;
177 
178 namespace std {
179 
180 template <>
181 struct is_error_condition_enum<cb::engine_errc> : public true_type { };
182 
183 }
184 
185 namespace cb {
186 // Backward compatibility - convert ENGINE_ERROR_CODE to engine_errc.
187 ENGINE_UTILITIES_PUBLIC_API
188 cb::engine_errc to_engine_errc(ENGINE_ERROR_CODE eec);
189 }
190