jaulib v1.4.1-10-ga2c96e0
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
exceptions.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020-2026 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef JAU_EXCEPTIONS_HPP_
26#define JAU_EXCEPTIONS_HPP_
27
28#include <ios>
29#include <stdexcept>
30#include <string>
31#include <system_error>
32
33#include <jau/cpp_lang_util.hpp>
34#include <jau/functional.hpp>
35
36namespace jau {
37
38 /** @defgroup Exceptions Exception types and functions
39 * Exception types and functions.
40 *
41 * @{
42 */
43
44 /**
45 * Handle given optional exception (nullable std::exception_ptr) and send std::exception::what() message to `stderr`
46 * @param eptr contains optional exception, may be `nullptr`
47 * @return true if `eptr` contained an exception pointer, message was not `nullptr`
48 */
49 inline bool handle_exception(std::exception_ptr eptr) { // NOLINT(performance-unnecessary-value-param) passing by value is OK
50 try {
51 if (eptr) {
52 std::rethrow_exception(eptr);
53 }
54 } catch (const std::exception &e) {
55 ::fprintf(stderr, "Exception caught: %s\n", e.what());
56 return true;
57 }
58 return false;
59 }
60
61 typedef jau::function<bool(const std::exception &)> exception_handler_t;
62
63 /**
64 * Handle given optional exception (nullable std::exception_ptr) and calls exception_handler_t
65 * @param eptr contains optional exception, may be `nullptr`
66 * @param eh exception_handler_t to process an eventual exception
67 * @return true if `eptr` contained an exception pointer, exception_handler_t result is returned. Otherwise false (no exception).
68 */
69 inline bool handle_exception(std::exception_ptr eptr, jau::exception_handler_t &eh) { // NOLINT(performance-unnecessary-value-param) passing by value is OK
70 try {
71 if (eptr) {
72 std::rethrow_exception(eptr);
73 }
74 } catch (const std::exception &e) {
75 return eh(e);
76 }
77 return false;
78 }
79
80 /**
81 // *************************************************
82 // *************************************************
83 // *************************************************
84 */
85
86 /** \addtogroup Exceptions
87 *
88 * @{
89 */
90
92 private:
93 // brief message
94 std::string msg_;
95 // optional whole backtrace
96 std::string backtrace_;
97 // brief message + optional whole backtrace
98 std::string what_;
99
100 protected:
101 ExceptionBase(std::string&& type, std::string const& m, const char* file, int line) noexcept;
102
103 public:
104 virtual ~ExceptionBase() noexcept = default;
105 ExceptionBase(const ExceptionBase& o) noexcept = default;
106 ExceptionBase(ExceptionBase&& o) noexcept = default;
107 ExceptionBase& operator=(const ExceptionBase& o) noexcept = default;
108 ExceptionBase& operator=(ExceptionBase&& o) noexcept = default;
109
110 /** Returns brief message. */
111 const std::string& brief_message() const noexcept { return msg_; }
112 /** Returns optional whole backtrace. */
113 const std::string& backtrace() const noexcept { return backtrace_; }
114 /** Returns brief message and optional whole backtrace, i.e. std::exception::what() string. */
115 const std::string& whole_message() const noexcept { return what_; }
116
117 /** Allow conversion to `const std::string&` using brief_message(), as required by Catch2's `REQUIRE_THROWS_MATCHES` */
118 operator const std::string&() const noexcept { return brief_message(); };
119
120 std::ostream& operator<<(std::ostream& out) noexcept {
121 return out << what_;
122 }
123
124 virtual const char* what() const noexcept {
125 return whole_message().c_str();
126 }
127 };
129 protected:
130 RuntimeExceptionBase(std::string&& type, std::string const& m, const char* file, int line) noexcept
131 : ExceptionBase(std::move(type), m, file, line) { }
132
133 public:
134 ~RuntimeExceptionBase() noexcept override = default;
135
136 RuntimeExceptionBase(const RuntimeExceptionBase& o) noexcept = default;
138 RuntimeExceptionBase& operator=(const RuntimeExceptionBase& o) noexcept = default;
139 RuntimeExceptionBase& operator=(RuntimeExceptionBase&& o) noexcept = default;
140 };
142 protected:
143 LogicErrorBase(std::string&& type, std::string const& m, const char* file, int line) noexcept
144 : ExceptionBase(std::move(type), m, file, line) { }
145
146 public:
147 ~LogicErrorBase() noexcept override = default;
148
149 LogicErrorBase(const LogicErrorBase& o) noexcept = default;
150 LogicErrorBase(LogicErrorBase&& o) noexcept = default;
151 LogicErrorBase& operator=(const LogicErrorBase& o) noexcept = default;
152 LogicErrorBase& operator=(LogicErrorBase&& o) noexcept = default;
153 };
155 protected:
156 std::error_code m_ec;
157 RuntimeSystemExceptionBase(std::string&& type, const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
158 : RuntimeExceptionBase(std::move(type), m, file, line), m_ec(ec) { }
159
160 public:
161 ~RuntimeSystemExceptionBase() noexcept override = default;
162
165 RuntimeSystemExceptionBase& operator=(const RuntimeSystemExceptionBase& o) noexcept = default;
166 RuntimeSystemExceptionBase& operator=(RuntimeSystemExceptionBase&& o) noexcept = default;
167
168 const std::error_code& code() const noexcept { return m_ec; }
169 };
170
172 public std::bad_alloc {
173 public:
174 OutOfMemoryError(std::string const& m, const char* file, int line)
175 : ExceptionBase("OutOfMemoryError", m, file, line), bad_alloc() { }
176
177 const char* what() const noexcept override {
178 return whole_message().c_str();
179 }
180 };
181
183 public std::runtime_error {
184 protected:
185 RuntimeException(std::string&& type, std::string const& m, const char* file, int line) noexcept
186 : RuntimeExceptionBase(std::move(type), m, file, line), runtime_error(whole_message()) { }
187
188 public:
189 RuntimeException(std::string const& m, const char* file, int line) noexcept
190 : RuntimeException("RuntimeException", m, file, line) { }
191
192 ~RuntimeException() noexcept override = default;
193
194 RuntimeException(const RuntimeException& o) noexcept = default;
195 RuntimeException(RuntimeException&& o) noexcept = default;
196 RuntimeException& operator=(const RuntimeException& o) noexcept = default;
197 RuntimeException& operator=(RuntimeException&& o) noexcept = default;
198
199 // base class std::exception:
200 const char* what() const noexcept override {
201 return whole_message().c_str();
202 }
203 };
205 public std::logic_error {
206 protected:
207 LogicError(std::string&& type, std::string const& m, const char* file, int line) noexcept
208 : LogicErrorBase(std::move(type), m, file, line), logic_error(whole_message()) { }
209
210 public:
211 LogicError(std::string const& m, const char* file, int line) noexcept
212 : LogicError("LogicErrorStd", m, file, line) { }
213
214 ~LogicError() noexcept override = default;
215
216 LogicError(const LogicError& o) noexcept = default;
217 LogicError(LogicError&& o) noexcept = default;
218 LogicError& operator=(const LogicError& o) noexcept = default;
219 LogicError& operator=(LogicError&& o) noexcept = default;
220
221 const char* what() const noexcept override {
222 return whole_message().c_str();
223 }
224 };
226 public std::system_error {
227 protected:
228 RuntimeSystemException(std::string&& type, const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
229 : RuntimeSystemExceptionBase(std::move(type), ec, m, file, line), system_error(ec, whole_message()) { }
230
231 public:
232 RuntimeSystemException(const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
233 : RuntimeSystemException("RuntimeSystemExceptionStd", ec, m, file, line) { }
234
235 ~RuntimeSystemException() noexcept override = default;
236
237 RuntimeSystemException(const RuntimeSystemException& o) noexcept = default;
239 RuntimeSystemException& operator=(const RuntimeSystemException& o) noexcept = default;
240 RuntimeSystemException& operator=(RuntimeSystemException&& o) noexcept = default;
241
242 const char* what() const noexcept override {
243 return whole_message().c_str();
244 }
245 };
246
248 public std::out_of_range {
249 protected:
250 IndexOutOfBoundsError(const char* file, int line, std::string&& type, std::string const& m) noexcept
251 : LogicErrorBase(std::move(type), m, file, line), out_of_range(whole_message()) { }
252
253 public:
254 IndexOutOfBoundsError(const std::size_t index, const std::size_t length, const char* file, int line) noexcept
255 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index " + std::to_string(index) + ", data length " + std::to_string(length)) { }
256
257 IndexOutOfBoundsError(const std::string& msg, const std::size_t index, const std::size_t length, const char* file, int line) noexcept
258 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", msg + ": index " + std::to_string(index) + ", data length " + std::to_string(length)) { }
259
260 IndexOutOfBoundsError(const std::string& index_s, const std::string& length_s, const char* file, int line) noexcept
261 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index " + index_s + ", data length " + length_s) { }
262
263 IndexOutOfBoundsError(const std::size_t index, const std::size_t count, const std::size_t length, const char* file, int line) noexcept
264 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index " + std::to_string(index) + ", count " + std::to_string(count) + ", data length " + std::to_string(length)) { }
265
266 const char* what() const noexcept override {
267 return whole_message().c_str();
268 }
269 };
270
272 public std::invalid_argument {
273 protected:
274 IllegalArgumentError(std::string&& type, std::string const& m, const char* file, int line) noexcept
275 : LogicErrorBase(std::move(type), m, file, line), invalid_argument(whole_message()) { }
276
277 public:
278 IllegalArgumentError(std::string const& m, const char* file, int line) noexcept
279 : IllegalArgumentError("IllegalArgumentError", m, file, line) { }
280
281 const char* what() const noexcept override {
282 return whole_message().c_str();
283 }
284 };
285
287 public std::domain_error {
288 protected:
289 IllegalStateError(std::string&& type, std::string const& m, const char* file, int line) noexcept
290 : LogicErrorBase(std::move(type), m, file, line), domain_error(whole_message()) { }
291
292 public:
293 IllegalStateError(std::string const& m, const char* file, int line) noexcept
294 : IllegalStateError("IllegalStateError", m, file, line) { }
295
296 const char* what() const noexcept override {
297 return whole_message().c_str();
298 }
299 };
300
302 public std::ios_base::failure {
303 public:
304 IOError(std::string const& m, const char* file, int line, const std::error_code& ec = std::io_errc::stream) noexcept
305 : RuntimeSystemExceptionBase("IOError", ec, m, file, line), failure(whole_message(), ec) { }
306
307 const char* what() const noexcept override {
308 return whole_message().c_str();
309 }
310 };
311
313 public:
314 InternalError(std::string const& m, const char* file, int line) noexcept
315 : RuntimeException("InternalError", m, file, line) { }
316 };
317
319 public:
320 NotImplementedException(std::string const& m, const char* file, int line) noexcept
321 : RuntimeException("NotImplementedException", m, file, line) { }
322 };
323
325 public:
326 NullPointerException(std::string const& m, const char* file, int line) noexcept
327 : RuntimeException("NullPointerException", m, file, line) { }
328 };
329
331 public:
332 UnsupportedOperationException(std::string const& m, const char* file, int line) noexcept
333 : RuntimeException("UnsupportedOperationException", m, file, line) { }
334 };
335
336 /**
337 // *************************************************
338 // *************************************************
339 // *************************************************
340 */
341
342 /**@}*/
343
344} // namespace jau
345
346#endif /* JAU_EXCEPTIONS_HPP_ */
Class template jau::function is a general-purpose static-polymorphic function wrapper.
const std::string & backtrace() const noexcept
Returns optional whole backtrace.
const std::string & whole_message() const noexcept
Returns brief message and optional whole backtrace, i.e.
LogicError(std::string &&type, std::string const &m, const char *file, int line) noexcept
OutOfMemoryError(std::string const &m, const char *file, int line)
bool handle_exception(std::exception_ptr eptr)
Handle given optional exception (nullable std::exception_ptr) and send std::exception::what() message...
RuntimeException(std::string const &m, const char *file, int line) noexcept
IndexOutOfBoundsError(const std::string &msg, const std::size_t index, const std::size_t length, const char *file, int line) noexcept
NullPointerException(std::string const &m, const char *file, int line) noexcept
ExceptionBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
UnsupportedOperationException(std::string const &m, const char *file, int line) noexcept
~RuntimeExceptionBase() noexcept override=default
RuntimeSystemExceptionBase(std::string &&type, const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
IndexOutOfBoundsError(const std::size_t index, const std::size_t count, const std::size_t length, const char *file, int line) noexcept
std::ostream & operator<<(std::ostream &out) noexcept
virtual ~ExceptionBase() noexcept=default
InternalError(std::string const &m, const char *file, int line) noexcept
IOError(std::string const &m, const char *file, int line, const std::error_code &ec=std::io_errc::stream) noexcept
const std::string & brief_message() const noexcept
Returns brief message.
RuntimeSystemException(const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
IllegalArgumentError(std::string &&type, std::string const &m, const char *file, int line) noexcept
IndexOutOfBoundsError(const std::size_t index, const std::size_t length, const char *file, int line) noexcept
const char * what() const noexcept override
const char * what() const noexcept override
jau::function< bool(const std::exception &)> exception_handler_t
virtual const char * what() const noexcept
~RuntimeSystemExceptionBase() noexcept override=default
IllegalStateError(std::string &&type, std::string const &m, const char *file, int line) noexcept
LogicErrorBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
NotImplementedException(std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
const char * what() const noexcept override
const char * what() const noexcept override
IllegalArgumentError(std::string const &m, const char *file, int line) noexcept
~RuntimeException() noexcept override=default
const char * what() const noexcept override
const char * what() const noexcept override
~RuntimeSystemException() noexcept override=default
LogicError(std::string const &m, const char *file, int line) noexcept
~LogicError() noexcept override=default
const std::error_code & code() const noexcept
IndexOutOfBoundsError(const std::string &index_s, const std::string &length_s, const char *file, int line) noexcept
IllegalStateError(std::string const &m, const char *file, int line) noexcept
RuntimeExceptionBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
RuntimeSystemException(std::string &&type, const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
IndexOutOfBoundsError(const char *file, int line, std::string &&type, std::string const &m) noexcept
~LogicErrorBase() noexcept override=default
RuntimeException(std::string &&type, std::string const &m, const char *file, int line) noexcept
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
STL namespace.