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