Gamp v0.0.7-67-g7798ac4
Gamp: Graphics, Audio, Multimedia and Processing
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 <exception>
29#include <ios>
30#include <stdexcept>
31#include <string>
32#include <system_error>
33
34#include <jau/cpp_lang_util.hpp>
35#include <jau/functional.hpp>
36
37namespace jau {
38
39 /** @defgroup Exceptions Exception types and functions
40 * Exception types and functions.
41 *
42 * @{
43 */
44
45 /// Exception handler method, should return true if not consumed or deemed an error. Shall be `noexcept` itself.
46 typedef jau::function<bool(const std::exception &, const char* file, int line)> exception_handler_t;
47
48 /**
49 * Handle given optional exception (nullable std::exception_ptr) and calls exception_handler_t
50 * @param eptr contains optional exception, may be `nullptr`
51 * @param eh exception_handler_t to process an eventual exception
52 * @return true if `eptr` contained an exception pointer, exception_handler_t result is returned. Otherwise false (no exception).
53 */
54 inline __attribute__((always_inline))
55 bool handle_exception(std::exception_ptr eptr, jau::exception_handler_t &eh, const char* file, int line) noexcept { // NOLINT(performance-unnecessary-value-param) passing by value is OK
56 if (eptr) {
57 try {
58 std::rethrow_exception(eptr);
59 } catch (const std::exception &e) {
60 return eh(e, file, line);
61 }
62 }
63 return false;
64 }
65
66 /**
67 // *************************************************
68 // *************************************************
69 // *************************************************
70 */
71
73 private:
74 // brief message
75 std::string msg_;
76 // optional whole backtrace
77 std::string backtrace_;
78 // brief message + optional whole backtrace
79 std::string what_;
80
81 protected:
82 ExceptionBase(std::string&& type, std::string const& m, const char* file, int line) noexcept;
83
84 public:
85 virtual ~ExceptionBase() noexcept = default;
86 ExceptionBase(const ExceptionBase& o) noexcept = default;
87 ExceptionBase(ExceptionBase&& o) noexcept = default;
88 ExceptionBase& operator=(const ExceptionBase& o) noexcept = default;
89 ExceptionBase& operator=(ExceptionBase&& o) noexcept = default;
90
91 /** Returns brief message. */
92 const std::string& brief_message() const noexcept { return msg_; }
93 /** Returns optional whole backtrace. */
94 const std::string& backtrace() const noexcept { return backtrace_; }
95 /** Returns brief message and optional whole backtrace, i.e. std::exception::what() string. */
96 const std::string& whole_message() const noexcept { return what_; }
97
98 /** Allow conversion to `const std::string&` using brief_message(), as required by Catch2's `REQUIRE_THROWS_MATCHES` */
99 operator const std::string&() const noexcept { return brief_message(); };
100
101 std::ostream& operator<<(std::ostream& out) noexcept {
102 return out << what_;
103 }
104
105 virtual const char* what() const noexcept {
106 return whole_message().c_str();
107 }
108 };
110 protected:
111 RuntimeExceptionBase(std::string&& type, std::string const& m, const char* file, int line) noexcept
112 : ExceptionBase(std::move(type), m, file, line) { }
113
114 public:
115 ~RuntimeExceptionBase() noexcept override = default;
116
117 RuntimeExceptionBase(const RuntimeExceptionBase& o) noexcept = default;
119 RuntimeExceptionBase& operator=(const RuntimeExceptionBase& o) noexcept = default;
120 RuntimeExceptionBase& operator=(RuntimeExceptionBase&& o) noexcept = default;
121 };
123 protected:
124 LogicErrorBase(std::string&& type, std::string const& m, const char* file, int line) noexcept
125 : ExceptionBase(std::move(type), m, file, line) { }
126
127 public:
128 ~LogicErrorBase() noexcept override = default;
129
130 LogicErrorBase(const LogicErrorBase& o) noexcept = default;
131 LogicErrorBase(LogicErrorBase&& o) noexcept = default;
132 LogicErrorBase& operator=(const LogicErrorBase& o) noexcept = default;
133 LogicErrorBase& operator=(LogicErrorBase&& o) noexcept = default;
134 };
136 protected:
137 std::error_code m_ec;
138 RuntimeSystemExceptionBase(std::string&& type, const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
139 : RuntimeExceptionBase(std::move(type), m, file, line), m_ec(ec) { }
140
141 public:
142 ~RuntimeSystemExceptionBase() noexcept override = default;
143
146 RuntimeSystemExceptionBase& operator=(const RuntimeSystemExceptionBase& o) noexcept = default;
147 RuntimeSystemExceptionBase& operator=(RuntimeSystemExceptionBase&& o) noexcept = default;
148
149 const std::error_code& code() const noexcept { return m_ec; }
150 };
151
153 public std::bad_alloc {
154 public:
155 OutOfMemoryError(std::string const& m, const char* file, int line)
156 : ExceptionBase("OutOfMemoryError", m, file, line), bad_alloc() { }
157
158 const char* what() const noexcept override {
159 return whole_message().c_str();
160 }
161 };
162
164 public std::runtime_error {
165 protected:
166 RuntimeException(std::string&& type, std::string const& m, const char* file, int line) noexcept
167 : RuntimeExceptionBase(std::move(type), m, file, line), runtime_error(whole_message()) { }
168
169 public:
170 RuntimeException(std::string const& m, const char* file, int line) noexcept
171 : RuntimeException("RuntimeException", m, file, line) { }
172
173 ~RuntimeException() noexcept override = default;
174
175 RuntimeException(const RuntimeException& o) noexcept = default;
176 RuntimeException(RuntimeException&& o) noexcept = default;
177 RuntimeException& operator=(const RuntimeException& o) noexcept = default;
178 RuntimeException& operator=(RuntimeException&& o) noexcept = default;
179
180 // base class std::exception:
181 const char* what() const noexcept override {
182 return whole_message().c_str();
183 }
184 };
186 public std::logic_error {
187 protected:
188 LogicError(std::string&& type, std::string const& m, const char* file, int line) noexcept
189 : LogicErrorBase(std::move(type), m, file, line), logic_error(whole_message()) { }
190
191 public:
192 LogicError(std::string const& m, const char* file, int line) noexcept
193 : LogicError("LogicErrorStd", m, file, line) { }
194
195 ~LogicError() noexcept override = default;
196
197 LogicError(const LogicError& o) noexcept = default;
198 LogicError(LogicError&& o) noexcept = default;
199 LogicError& operator=(const LogicError& o) noexcept = default;
200 LogicError& operator=(LogicError&& o) noexcept = default;
201
202 const char* what() const noexcept override {
203 return whole_message().c_str();
204 }
205 };
207 public std::system_error {
208 protected:
209 RuntimeSystemException(std::string&& type, const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
210 : RuntimeSystemExceptionBase(std::move(type), ec, m, file, line), system_error(ec, whole_message()) { }
211
212 public:
213 RuntimeSystemException(const std::error_code& ec, std::string const& m, const char* file, int line) noexcept
214 : RuntimeSystemException("RuntimeSystemExceptionStd", ec, m, file, line) { }
215
216 ~RuntimeSystemException() noexcept override = default;
217
218 RuntimeSystemException(const RuntimeSystemException& o) noexcept = default;
220 RuntimeSystemException& operator=(const RuntimeSystemException& o) noexcept = default;
221 RuntimeSystemException& operator=(RuntimeSystemException&& o) noexcept = default;
222
223 const char* what() const noexcept override {
224 return whole_message().c_str();
225 }
226 };
227
229 public std::out_of_range {
230 protected:
231 IndexOutOfBoundsError(const char* file, int line, std::string&& type, std::string const& m) noexcept
232 : LogicErrorBase(std::move(type), m, file, line), out_of_range(whole_message()) { }
233
234 public:
235 IndexOutOfBoundsError(const std::size_t index, const std::size_t length, const char* file, int line) noexcept
236 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index " + std::to_string(index) + ", data length " + std::to_string(length)) { }
237
238 IndexOutOfBoundsError(const std::string& msg, const std::size_t index, const std::size_t length, const char* file, int line) noexcept
239 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", msg + ": index " + std::to_string(index) + ", data length " + std::to_string(length)) { }
240
241 IndexOutOfBoundsError(const std::string& index_s, const std::string& length_s, const char* file, int line) noexcept
242 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index " + index_s + ", data length " + length_s) { }
243
244 IndexOutOfBoundsError(const std::size_t index, const std::size_t count, const std::size_t length, const char* file, int line) noexcept
245 : IndexOutOfBoundsError(file, line, "IndexOutOfBoundsError", "Index " + std::to_string(index) + ", count " + std::to_string(count) + ", data length " + std::to_string(length)) { }
246
247 const char* what() const noexcept override {
248 return whole_message().c_str();
249 }
250 };
251
253 public std::invalid_argument {
254 protected:
255 IllegalArgumentError(std::string&& type, std::string const& m, const char* file, int line) noexcept
256 : LogicErrorBase(std::move(type), m, file, line), invalid_argument(whole_message()) { }
257
258 public:
259 IllegalArgumentError(std::string const& m, const char* file, int line) noexcept
260 : IllegalArgumentError("IllegalArgumentError", m, file, line) { }
261
262 const char* what() const noexcept override {
263 return whole_message().c_str();
264 }
265 };
266
268 public std::domain_error {
269 protected:
270 IllegalStateError(std::string&& type, std::string const& m, const char* file, int line) noexcept
271 : LogicErrorBase(std::move(type), m, file, line), domain_error(whole_message()) { }
272
273 public:
274 IllegalStateError(std::string const& m, const char* file, int line) noexcept
275 : IllegalStateError("IllegalStateError", m, file, line) { }
276
277 const char* what() const noexcept override {
278 return whole_message().c_str();
279 }
280 };
281
283 public std::ios_base::failure {
284 public:
285 IOError(std::string const& m, const char* file, int line, const std::error_code& ec = std::io_errc::stream) noexcept
286 : RuntimeSystemExceptionBase("IOError", ec, m, file, line), failure(whole_message(), ec) { }
287
288 const char* what() const noexcept override {
289 return whole_message().c_str();
290 }
291 };
292
294 public:
295 InternalError(std::string const& m, const char* file, int line) noexcept
296 : RuntimeException("InternalError", m, file, line) { }
297 };
298
300 public:
301 NotImplementedException(std::string const& m, const char* file, int line) noexcept
302 : RuntimeException("NotImplementedException", m, file, line) { }
303 };
304
306 public:
307 NullPointerException(std::string const& m, const char* file, int line) noexcept
308 : RuntimeException("NullPointerException", m, file, line) { }
309 };
310
312 public:
313 UnsupportedOperationException(std::string const& m, const char* file, int line) noexcept
314 : RuntimeException("UnsupportedOperationException", m, file, line) { }
315 };
316
317 /**@}*/
318
319} // namespace jau
320
321#endif /* JAU_EXCEPTIONS_HPP_ */
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.
ExceptionBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
std::ostream & operator<<(std::ostream &out) noexcept
virtual ~ExceptionBase() noexcept=default
const std::string & brief_message() const noexcept
Returns brief message.
virtual const char * what() const noexcept
IOError(std::string const &m, const char *file, int line, const std::error_code &ec=std::io_errc::stream) noexcept
const char * what() const noexcept override
IllegalArgumentError(std::string &&type, std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
IllegalArgumentError(std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
IllegalStateError(std::string &&type, std::string const &m, const char *file, int line) noexcept
IllegalStateError(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
IndexOutOfBoundsError(const std::size_t index, const std::size_t count, const std::size_t length, 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
IndexOutOfBoundsError(const std::string &index_s, const std::string &length_s, const char *file, int line) noexcept
IndexOutOfBoundsError(const char *file, int line, std::string &&type, std::string const &m) noexcept
InternalError(std::string const &m, const char *file, int line) noexcept
LogicErrorBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
~LogicErrorBase() noexcept override=default
LogicError(std::string &&type, std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
LogicError(std::string const &m, const char *file, int line) noexcept
~LogicError() noexcept override=default
NotImplementedException(std::string const &m, const char *file, int line) noexcept
NullPointerException(std::string const &m, const char *file, int line) noexcept
OutOfMemoryError(std::string const &m, const char *file, int line)
const char * what() const noexcept override
~RuntimeExceptionBase() noexcept override=default
RuntimeExceptionBase(std::string &&type, std::string const &m, const char *file, int line) noexcept
RuntimeException(std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
~RuntimeException() noexcept override=default
RuntimeException(std::string &&type, std::string const &m, const char *file, int line) noexcept
RuntimeSystemExceptionBase(std::string &&type, const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
~RuntimeSystemExceptionBase() noexcept override=default
const std::error_code & code() const noexcept
RuntimeSystemException(const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
const char * what() const noexcept override
~RuntimeSystemException() noexcept override=default
RuntimeSystemException(std::string &&type, const std::error_code &ec, std::string const &m, const char *file, int line) noexcept
UnsupportedOperationException(std::string const &m, const char *file, int line) noexcept
Class template jau::function is a general-purpose static-polymorphic function wrapper.
jau::function< bool(const std::exception &, const char *file, int line)> exception_handler_t
Exception handler method, should return true if not consumed or deemed an error. Shall be noexcept it...
bool handle_exception(std::exception_ptr eptr, const char *file, int line) noexcept
Handle given optional exception (nullable std::exception_ptr) and send std::exception::what() message...
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
STL namespace.