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#include <memcached/engine_error.h>
18
19#include <iostream>
20#include <map>
21#include <string>
22
23/**
24 * engine_error_category provides the mapping from the engine error codes to
25 * a textual mapping and is used together with the std::system_error.
26 */
27class engine_category : public std::error_category {
28public:
29    const char* name() const NOEXCEPT override {
30        return "engine error codes";
31    }
32
33    std::string message(int code) const override {
34        return to_string(cb::engine_errc(code));
35    }
36
37    std::error_condition default_error_condition(int code) const NOEXCEPT override {
38        return std::error_condition(code, *this);
39    }
40};
41
42const std::error_category& cb::engine_error_category() NOEXCEPT {
43    static engine_category category_instance;
44    return category_instance;
45}
46
47std::string cb::to_string(cb::engine_errc code) {
48    switch (code) {
49    case cb::engine_errc::success:
50        return "success";
51    case cb::engine_errc::no_such_key:
52        return "no such key";
53    case cb::engine_errc::key_already_exists:
54        return "key already exists";
55    case cb::engine_errc::no_memory:
56        return "no memory";
57    case cb::engine_errc::not_stored:
58        return "not stored";
59    case cb::engine_errc::invalid_arguments:
60        return "invalid arguments";
61    case cb::engine_errc::not_supported:
62        return "not supported";
63    case cb::engine_errc::would_block:
64        return "would block";
65    case cb::engine_errc::too_big:
66        return "too big";
67    case cb::engine_errc::want_more:
68        return "want more";
69    case cb::engine_errc::disconnect:
70        return "disconnect";
71    case cb::engine_errc::no_access:
72        return "no access";
73    case cb::engine_errc::not_my_vbucket:
74        return "not my vbucket";
75    case cb::engine_errc::temporary_failure:
76        return "temporary failure";
77    case cb::engine_errc::out_of_range:
78        return "out of range";
79    case cb::engine_errc::rollback:
80        return "rollback";
81    case cb::engine_errc::no_bucket:
82        return "no bucket";
83    case cb::engine_errc::too_busy:
84        return "too busy";
85    case cb::engine_errc::authentication_stale:
86        return "authentication stale";
87    case cb::engine_errc::delta_badval:
88        return "delta bad value";
89    case cb::engine_errc::locked:
90        return "resource is locked";
91    case cb::engine_errc::locked_tmpfail:
92        return "resource is locked; tmpfail";
93    case cb::engine_errc::failed:
94        return "generic failure";
95    case cb::engine_errc::unknown_collection:
96        return "unknown collection";
97    case cb::engine_errc::predicate_failed:
98        return "predicate_failed";
99    case cb::engine_errc::no_collections_manifest:
100        return "no_collections_manifest";
101    };
102    throw std::invalid_argument(
103        "engine_error_category::message: code does not represent a "
104            "legal error code: " + std::to_string(int(code)));
105}
106
107void cb::PrintTo(cb::engine_errc ev, ::std::ostream* os) {
108    *os << cb::to_string(ev);
109}
110
111std::ostream& operator<<(std::ostream& os, cb::engine_errc ec) {
112    cb::PrintTo(ec, &os);
113    return os;
114}
115
116cb::engine_errc cb::to_engine_errc(ENGINE_ERROR_CODE eec) {
117    switch (eec) {
118        case ENGINE_SUCCESS: return cb::engine_errc::success;
119        case ENGINE_KEY_ENOENT: return cb::engine_errc::no_such_key;
120        case ENGINE_KEY_EEXISTS: return cb::engine_errc::key_already_exists;
121        case ENGINE_ENOMEM: return cb::engine_errc::no_memory;
122        case ENGINE_NOT_STORED: return cb::engine_errc::not_stored;
123        case ENGINE_EINVAL: return cb::engine_errc::invalid_arguments;
124        case ENGINE_ENOTSUP: return cb::engine_errc::not_supported;
125        case ENGINE_EWOULDBLOCK: return cb::engine_errc::would_block;
126        case ENGINE_E2BIG: return cb::engine_errc::too_big;
127        case ENGINE_WANT_MORE: return cb::engine_errc::want_more;
128        case ENGINE_DISCONNECT: return cb::engine_errc::disconnect;
129        case ENGINE_EACCESS: return cb::engine_errc::no_access;
130        case ENGINE_NOT_MY_VBUCKET: return cb::engine_errc::not_my_vbucket;
131        case ENGINE_TMPFAIL: return cb::engine_errc::temporary_failure;
132        case ENGINE_ERANGE: return cb::engine_errc::out_of_range;
133        case ENGINE_ROLLBACK: return cb::engine_errc::rollback;
134        case ENGINE_NO_BUCKET: return cb::engine_errc::no_bucket;
135        case ENGINE_EBUSY: return cb::engine_errc::too_busy;
136        case ENGINE_AUTH_STALE: return cb::engine_errc::authentication_stale;
137        case ENGINE_DELTA_BADVAL: return cb::engine_errc::delta_badval;
138        case ENGINE_LOCKED: return cb::engine_errc::locked;
139        case ENGINE_LOCKED_TMPFAIL: return cb::engine_errc::locked_tmpfail;
140        case ENGINE_UNKNOWN_COLLECTION: return cb::engine_errc::unknown_collection;
141        case ENGINE_FAILED: return cb::engine_errc::failed;
142        case ENGINE_PREDICATE_FAILED: return cb::engine_errc::predicate_failed;
143    }
144    throw std::invalid_argument(
145            "cb::to_engine_errc: invalid ENGINE_ERROR_CODE " +
146            std::to_string(eec));
147}
148