/src/kea/src/lib/exceptions/exceptions.h
Line | Count | Source |
1 | | // Copyright (C) 2009-2024 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 |
46 | 5.11M | 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. |
85 | 0 | 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. |
90 | 0 | 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. |
95 | 0 | 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: |
117 | | OutOfRange(const char* file, size_t line, const char* what) : |
118 | 11.5k | 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: |
126 | | InvalidParameter(const char* file, size_t line, const char* what) : |
127 | 5.66k | 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: |
134 | | BadValue(const char* file, size_t line, const char* what) : |
135 | 305k | 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: |
145 | | InvalidOperation(const char* file, size_t line, const char* what) : |
146 | 1.23k | 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: |
155 | | Unexpected(const char* file, size_t line, const char* what) : |
156 | 3.59k | 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: |
168 | | NotImplemented(const char* file, size_t line, const char* what) : |
169 | 6.17k | 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: |
177 | | NotFound(const char* file, size_t line, const char* what) : |
178 | 0 | 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: |
185 | | MultiThreadingInvalidOperation(const char* file, size_t line, const char* what) : |
186 | 0 | 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 | 5.13M | do { \ |
212 | 5.13M | std::ostringstream oss__; \ |
213 | 5.13M | oss__ << stream; \ |
214 | 5.13M | throw type(__FILE__, __LINE__, oss__.str().c_str()); \ |
215 | 5.13M | } 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 | 0 | do { \ |
232 | 0 | std::ostringstream oss__; \ |
233 | 0 | oss__ << stream; \ |
234 | 0 | throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2); \ |
235 | 0 | } 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 | 0 | do { \ |
242 | 0 | std::ostringstream oss__; \ |
243 | 0 | oss__ << stream; \ |
244 | 0 | throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2,\ |
245 | 0 | param3); \ |
246 | 0 | } 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 | 0 | do { \ |
253 | 0 | std::ostringstream oss__; \ |
254 | 0 | oss__ << stream; \ |
255 | 0 | throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2,\ |
256 | 0 | param3, param4); \ |
257 | 0 | } while (1) |
258 | | |
259 | | } |
260 | | #endif // EXCEPTIONS_H |