1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #pragma once
32 
33 #include <cstdint>
34 #include <iosfwd>
35 #include <string>
36 
37 #include "mongo/base/string_data.h"
38 #include "mongo/platform/compiler.h"
39 
40 namespace mongo {
41 
42 class Status;
43 
44 enum class ErrorCategory {
45     //#for $cat in $categories
46     ${cat.name},
47     //#end for
48 };
49 
50 /**
51  * This is a generated class containing a table of error codes and their corresponding error
52  * strings. The class is derived from the definitions in src/mongo/base/error_codes.err file and the
53  * src/mongo/base/error_codes.tpl.h template.
54  *
55  * Do not update this file directly. Update src/mongo/base/error_codes.err instead.
56  */
57 class ErrorCodes {
58 public:
59     // Explicitly 32-bits wide so that non-symbolic values,
60     // like uassert codes, are valid.
61     enum Error : std::int32_t {
62         //#for $ec in $codes
63         $ec.name = $ec.code,
64         //#end for
65         MaxError
66     };
67 
68     static std::string errorString(Error err);
69 
70     /**
71      * Parses an Error from its "name".  Returns UnknownError if "name" is unrecognized.
72      *
73      * NOTE: Also returns UnknownError for the string "UnknownError".
74      */
75     static Error fromString(StringData name);
76 
77     /**
78      * Reuses a unique numeric code in a way that supresses the duplicate code detection. This
79      * should only be used when testing error cases to ensure that the code under test fails in the
80      * right place. It should NOT be used in non-test code to either make a new error site (use
81      * ErrorCodes::Error(CODE) for that) or to see if a specific failure case occurred (use named
82      * codes for that).
83      */
duplicateCodeForTest(int code)84     static Error duplicateCodeForTest(int code) {
85         return static_cast<Error>(code);
86     }
87 
88     /**
89      * Generic predicate to test if a given error code is in a category.
90      *
91      * This version is intended to simplify forwarding by Status and DBException. Non-generic
92      * callers should just use the specific isCategoryName() methods instead.
93      */
94     template <ErrorCategory category>
95     static bool isA(Error code);
96 
97     //#for $cat in $categories
98     static bool is${cat.name}(Error code);
99     //#end for
100 };
101 
102 std::ostream& operator<<(std::ostream& stream, ErrorCodes::Error code);
103 
104 //#for $cat in $categories
105 template <>
106 inline bool ErrorCodes::isA<ErrorCategory::$cat.name>(Error code) {
107     return is${cat.name}(code);
108 }
109 //#end for
110 
111 /**
112  * This namespace contains implementation details for our error handling code and should not be used
113  * directly in general code.
114  */
115 namespace error_details {
116 
117 template <int32_t code>
118 constexpr bool isNamedCode = false;
119 //#for $ec in $codes
120 template <>
121 constexpr inline bool isNamedCode<ErrorCodes::$ec.name> = true;
122 //#end for
123 
124 MONGO_COMPILER_NORETURN void throwExceptionForStatus(const Status& status);
125 
126 template <ErrorCategory... categories>
127 struct CategoryList;
128 
129 template <ErrorCodes::Error code>
130 struct ErrorCategoriesForImpl {
131     using type = CategoryList<>;
132 };
133 
134 //#for $ec in $codes:
135 //#if $ec.categories
136 template <>
137 struct ErrorCategoriesForImpl<ErrorCodes::$ec.name> {
138     using type = CategoryList<
139         //#for $i, $cat in enumerate($ec.categories)
140         //#set $comma = '' if i == len($ec.categories) - 1 else ', '
141         ErrorCategory::$cat$comma
142         //#end for
143         >;
144 };
145 //#end if
146 //#end for
147 
148 template <ErrorCodes::Error code>
149 using ErrorCategoriesFor = typename ErrorCategoriesForImpl<code>::type;
150 
151 }  // namespace error_details
152 
153 }  // namespace mongo
154