1 // Copyright (C) 2009-2021 Internet Systems Consortium, Inc. ("ISC") 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, v. 2.0. If a copy of the MPL was not distributed with this 5 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 7 #ifndef EXCEPTIONS_H 8 #define EXCEPTIONS_H 1 9 10 #include <stdexcept> 11 #include <string> 12 #include <sstream> 13 14 namespace isc { 15 16 /// 17 /// This is a base class for exceptions thrown from the DNS library module. 18 /// Normally, the exceptions are thrown via a convenient shortcut macro, 19 /// @ref isc_throw, which automatically gives trivial parameters for the 20 /// exception such as the file name and line number where the exception is 21 /// triggered. 22 /// 23 class Exception : public std::exception { 24 public: 25 /// 26 /// \name Constructors and Destructor 27 /// 28 //@{ 29 /// \brief Constructor for a given type for exceptions with file name and 30 /// file line number. 31 /// 32 /// @param file the file name where the exception was thrown. 33 /// @param line the line in \a file where the exception was thrown. 34 /// @param what a description (type) of the exception. 35 Exception(const char* file, size_t line, const char* what); 36 37 /// \brief Constructor for a given type for exceptions with file name and 38 /// file line number. 39 /// 40 /// @param file the file name where the exception was thrown. 41 /// @param line the line in \a file where the exception was thrown. 42 /// @param what a description (type) of the exception. 43 Exception(const char* file, size_t line, const std::string& what); 44 45 /// The destructor ~Exception()46 virtual ~Exception() throw() {} 47 //@} 48 private: 49 /// 50 /// The assignment operator is intentionally disabled. 51 /// 52 void operator=(const Exception& src); 53 54 public: 55 /// 56 /// \name Methods Reimplemented against the Standard Exception Class 57 /// 58 //@{ 59 /// \brief Returns a C-style character string of the cause of the exception. 60 /// 61 /// Note: we normally don't use exception specifications, but this is an 62 /// "exception" to that policy as it's enforced by the base class. 63 /// 64 /// @return A C-style character string of the exception cause. 65 virtual const char* what() const throw(); 66 67 /// \brief Returns a C-style character string of the cause of exception. 68 /// 69 /// With verbose set to true, also returns file name and line numbers. 70 /// Note that we can't simply define a single what() method with parameters, 71 /// as the compiler would complain that it shadows the base class method. 72 /// 73 /// \param verbose if set to true, filename and line number will be added. 74 /// \return A C-style character string of the exception cause. 75 virtual const char* what(bool verbose) const throw(); 76 //@} 77 78 /// 79 /// \name Getter Methods 80 /// 81 //@{ 82 /// \brief Gets a string describing the cause of the exception. 83 /// 84 /// @return the cause string. getMessage()85 const std::string& getMessage() const { return (what_); } 86 87 /// \brief Gets the file name where the exception was thrown. 88 /// 89 /// @return a C-style string of the file name. getFile()90 const char* getFile() const { return (file_); } 91 92 /// \brief Gets the line number of the file where the exception was thrown. 93 /// 94 /// @return an integer specifying the line number. getLine()95 size_t getLine() const { return (line_); } 96 //@} 97 98 private: 99 100 /// Specifies the filename where this exception was raised 101 const char* const file_; 102 103 /// Specifies the line number where this exception was raised 104 size_t line_; 105 106 /// Specifies actual content of the exception 107 const std::string what_; 108 109 /// Specifies actual context of the exception (with file:line added) 110 std::string verbose_what_; 111 }; 112 113 /// \brief A generic exception that is thrown if a parameter given 114 /// to a method would refer to or modify out-of-range data. 115 class OutOfRange : public Exception { 116 public: OutOfRange(const char * file,size_t line,const char * what)117 OutOfRange(const char* file, size_t line, const char* what) : 118 isc::Exception(file, line, what) {} 119 }; 120 121 /// \brief A generic exception that is thrown if a parameter given 122 /// to a method or function is considered invalid and no other specific 123 /// exceptions are suitable to describe the error. 124 class InvalidParameter : public Exception { 125 public: InvalidParameter(const char * file,size_t line,const char * what)126 InvalidParameter(const char* file, size_t line, const char* what) : 127 isc::Exception(file, line, what) {} 128 }; 129 130 /// \brief A generic exception that is thrown if a parameter given 131 /// to a method is considered invalid in that context. 132 class BadValue : public Exception { 133 public: BadValue(const char * file,size_t line,const char * what)134 BadValue(const char* file, size_t line, const char* what) : 135 isc::Exception(file, line, what) {} 136 }; 137 138 /// \brief A generic exception that is thrown if a function is called 139 /// in a prohibited way. 140 /// 141 /// For example, this can happen if a class method is called when the object's 142 /// state does not allow that particular method. 143 class InvalidOperation : public Exception { 144 public: InvalidOperation(const char * file,size_t line,const char * what)145 InvalidOperation(const char* file, size_t line, const char* what) : 146 isc::Exception(file, line, what) {} 147 }; 148 149 /// 150 /// \brief A generic exception that is thrown when an unexpected 151 /// error condition occurs. 152 /// 153 class Unexpected : public Exception { 154 public: Unexpected(const char * file,size_t line,const char * what)155 Unexpected(const char* file, size_t line, const char* what) : 156 isc::Exception(file, line, what) {} 157 }; 158 159 /// 160 /// \brief A generic exception that is thrown when a function is 161 /// not implemented. 162 /// 163 /// This may be due to unfinished implementation or in case the 164 /// function isn't even planned to be provided for that situation, 165 /// i.e. not yet implemented or not supported. 166 class NotImplemented : public Exception { 167 public: NotImplemented(const char * file,size_t line,const char * what)168 NotImplemented(const char* file, size_t line, const char* what) : 169 isc::Exception(file, line, what) {} 170 }; 171 172 /// 173 /// \brief A generic exception that is thrown when an object can 174 /// not be found. 175 class NotFound : public Exception { 176 public: NotFound(const char * file,size_t line,const char * what)177 NotFound(const char* file, size_t line, const char* what) : 178 isc::Exception(file, line, what) {} 179 }; 180 181 /// \brief Exception thrown when a worker thread is trying to stop or pause the 182 /// respective thread pool (which would result in a dead-lock). 183 class MultiThreadingInvalidOperation : public Exception { 184 public: MultiThreadingInvalidOperation(const char * file,size_t line,const char * what)185 MultiThreadingInvalidOperation(const char* file, size_t line, const char* what) : 186 isc::Exception(file, line, what) {}; 187 }; 188 189 /// 190 /// A shortcut macro to insert known values into exception arguments. 191 /// 192 /// It allows the \c stream argument to be part of a statement using an 193 /// \c ostream object and its \c operator<<. For example, 194 /// \code int x = 10; 195 /// isc_throw(SomeException, "Error happened, parameter: " << x); 196 /// \endcode 197 /// will throw an exception of class \c SomeException whose \c what string 198 /// will be <code>"Error happened, parameter: 10"</code>. 199 /// 200 /// Note: the stream related operations or creation of the exception object 201 /// may itself throw an exception (specifically \c std::bad_alloc). 202 /// Even though it should be very rare, we may have to address this issue later. 203 /// 204 /// Note: in general we hate macros and avoid using it in the code. This is 205 /// one of few exceptions to that policy. inline functions cannot be used 206 /// for embedding \c __FILE__ and \c __LINE__. This is the main reason why 207 /// this is defined as a macro. The convenience for the ostream is a secondary 208 /// purpose (if that were the only possible reason we should rather avoid 209 /// using a macro). 210 #define isc_throw(type, stream) \ 211 do { \ 212 std::ostringstream oss__; \ 213 oss__ << stream; \ 214 throw type(__FILE__, __LINE__, oss__.str().c_str()); \ 215 } while (1) 216 217 /// 218 /// Similar as isc_throw, but allows the exception to have one additional 219 /// parameter (the stream/text goes first) 220 #define isc_throw_1(type, stream, param1) \ 221 do { \ 222 std::ostringstream oss__; \ 223 oss__ << stream; \ 224 throw type(__FILE__, __LINE__, oss__.str().c_str(), param1); \ 225 } while (1) 226 227 /// 228 /// Similar as isc_throw, but allows the exception to have two additional 229 /// parameters (the stream/text goes first) 230 #define isc_throw_2(type, stream, param1, param2) \ 231 do { \ 232 std::ostringstream oss__; \ 233 oss__ << stream; \ 234 throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2); \ 235 } while (1) 236 237 /// 238 /// Similar as isc_throw, but allows the exception to have three additional 239 /// parameters (the stream/text goes first) 240 #define isc_throw_3(type, stream, param1, param2, param3) \ 241 do { \ 242 std::ostringstream oss__; \ 243 oss__ << stream; \ 244 throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2,\ 245 param3); \ 246 } while (1) 247 248 /// 249 /// Similar as isc_throw, but allows the exception to have four additional 250 /// parameters (the stream/text goes first) 251 #define isc_throw_4(type, stream, param1, param2, param3, param4) \ 252 do { \ 253 std::ostringstream oss__; \ 254 oss__ << stream; \ 255 throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2,\ 256 param3, param4); \ 257 } while (1) 258 259 } 260 #endif // EXCEPTIONS_H 261 262 // Local Variables: 263 // mode: c++ 264 // End: 265