Commit | Line | Data |
---|---|---|
53cd1e22 JG |
1 | /* |
2 | * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: LGPL-2.1-only | |
5 | * | |
6 | */ | |
7 | ||
8 | #ifndef LTTNG_EXCEPTION_H_ | |
9 | #define LTTNG_EXCEPTION_H_ | |
10 | ||
9f4d1ef3 JG |
11 | #include <common/string-utils/c-string-view.hpp> |
12 | ||
28f23191 JG |
13 | #include <lttng/lttng-error.h> |
14 | ||
1fa11e2f KS |
15 | #include <vendor/optional.hpp> |
16 | ||
53cd1e22 | 17 | #include <stdexcept> |
28f23191 | 18 | #include <string> |
53cd1e22 JG |
19 | #include <system_error> |
20 | ||
9f4d1ef3 JG |
21 | #define LTTNG_SOURCE_LOCATION() lttng::source_location(__FILE__, __func__, __LINE__) |
22 | ||
0038180d | 23 | #define LTTNG_THROW_CTL(msg, error_code) \ |
9f4d1ef3 | 24 | throw lttng::ctl::error(msg, error_code, LTTNG_SOURCE_LOCATION()) |
53cd1e22 | 25 | #define LTTNG_THROW_POSIX(msg, errno_code) \ |
9f4d1ef3 | 26 | throw lttng::posix_error(msg, errno_code, LTTNG_SOURCE_LOCATION()) |
16d64977 JG |
27 | #define LTTNG_THROW_ERROR(msg) throw lttng::runtime_error(msg, LTTNG_SOURCE_LOCATION()) |
28 | #define LTTNG_THROW_OUT_OF_RANGE(msg) throw lttng::out_of_range(msg, LTTNG_SOURCE_LOCATION()) | |
1fa11e2f KS |
29 | #define LTTNG_THROW_ALLOCATION_FAILURE_ERROR(msg) \ |
30 | throw lttng::allocation_failure(msg, LTTNG_SOURCE_LOCATION()) | |
31 | #define LTTNG_THROW_ALLOCATION_FAILURE_WITH_SIZE_ERROR(msg, allocation_size) \ | |
d9a970b7 | 32 | throw lttng::allocation_failure(msg, allocation_size, LTTNG_SOURCE_LOCATION()) |
b6bbb1d6 | 33 | #define LTTNG_THROW_UNSUPPORTED_ERROR(msg) \ |
9f4d1ef3 | 34 | throw lttng::unsupported_error(msg, LTTNG_SOURCE_LOCATION()) |
baac5795 | 35 | #define LTTNG_THROW_COMMUNICATION_ERROR(msg) \ |
9f4d1ef3 JG |
36 | throw lttng::communication_error(msg, LTTNG_SOURCE_LOCATION()) |
37 | #define LTTNG_THROW_PROTOCOL_ERROR(msg) throw lttng::protocol_error(msg, LTTNG_SOURCE_LOCATION()) | |
baac5795 | 38 | #define LTTNG_THROW_INVALID_ARGUMENT_ERROR(msg) \ |
9f4d1ef3 | 39 | throw lttng::invalid_argument_error(msg, LTTNG_SOURCE_LOCATION()) |
53cd1e22 JG |
40 | |
41 | namespace lttng { | |
62d6b5d0 | 42 | /* |
9f4d1ef3 JG |
43 | * @class source_location |
44 | * @brief Represents the location in the source code where an exception was thrown. | |
45 | * | |
46 | * The source_location class captures the file name, function name, and line number | |
47 | * of the source code where an exception occurs. This information is useful for | |
48 | * debugging and logging purposes. | |
49 | * | |
50 | * @details | |
51 | * This class provides: | |
52 | * - The name of the source file (file_name). | |
53 | * - The name of the function (function_name). | |
54 | * - The line number in the source file (line_number). | |
55 | * | |
56 | * Example usage: | |
57 | * @code | |
58 | * try { | |
59 | * // Code that may throw an exception. | |
60 | * } catch (const lttng::runtime_error& ex) { | |
61 | * // Handle the exception, possibly logging location information. | |
62 | * ERR_FMT("{} [{}]", ex.what(), ex.source_location); | |
63 | * } | |
64 | * @endcode | |
65 | */ | |
66 | class source_location { | |
67 | public: | |
68 | source_location(lttng::c_string_view file_name_, | |
69 | lttng::c_string_view function_name_, | |
70 | unsigned int line_number_) : | |
71 | file_name(file_name_), function_name(function_name_), line_number(line_number_) | |
72 | { | |
73 | } | |
74 | ||
75 | lttng::c_string_view file_name; | |
76 | lttng::c_string_view function_name; | |
77 | unsigned int line_number; | |
78 | }; | |
79 | ||
62d6b5d0 | 80 | /* |
9f4d1ef3 JG |
81 | * @class runtime_error |
82 | * @brief Base type for all LTTng exceptions. | |
83 | * | |
84 | * Exceptions in the project provide an error message (through the usual what() method), but that | |
85 | * message may not include the whole context of the error. For example, it is not always desirable | |
86 | * to include the source location in a user-facing message. | |
87 | * | |
88 | * As such, exception handlers should mind the type of the exception being thrown and consider | |
89 | * what context is suitable to extract (e.g. some context may only be relevant at the DEBUG logging | |
90 | * level, while the error message may be user-facing). | |
91 | * | |
92 | * Since 'what()' is marked as noexcept, derived classes should format their generic message during | |
93 | * their construction and pass it to the runtime_error constructor. | |
94 | */ | |
baac5795 JG |
95 | class runtime_error : public std::runtime_error { |
96 | public: | |
9f4d1ef3 JG |
97 | runtime_error(const std::string& msg, const lttng::source_location& source_location); |
98 | ||
99 | lttng::source_location source_location; | |
baac5795 | 100 | }; |
53cd1e22 | 101 | |
62d6b5d0 | 102 | /* |
d9a970b7 JG |
103 | * @class allocation_failure |
104 | * @brief Represents an allocation failure. | |
105 | * | |
106 | * Thrown when an allocation fails. Differs from bad_alloc in that it offers a message and a | |
107 | * source location. | |
108 | */ | |
109 | class allocation_failure : public lttng::runtime_error { | |
110 | public: | |
1fa11e2f KS |
111 | explicit allocation_failure(const std::string& msg, |
112 | const lttng::source_location& source_location); | |
d9a970b7 JG |
113 | explicit allocation_failure(const std::string& msg, |
114 | std::size_t allocation_size, | |
115 | const lttng::source_location& source_location); | |
116 | ||
1fa11e2f | 117 | nonstd::optional<std::size_t> allocation_size; |
d9a970b7 JG |
118 | }; |
119 | ||
62d6b5d0 | 120 | /* |
16d64977 JG |
121 | * @class out_of_range |
122 | * @brief Represents an out of range access error. | |
123 | * | |
124 | * Thrown when attempting to access a container out of its valid range (e.g., advancing an iterator | |
125 | * past end()). | |
126 | */ | |
127 | class out_of_range : public lttng::runtime_error { | |
128 | public: | |
129 | explicit out_of_range(const std::string& msg, | |
130 | const lttng::source_location& source_location); | |
131 | }; | |
132 | ||
62d6b5d0 | 133 | /* |
9f4d1ef3 JG |
134 | * @class unsupported_error |
135 | * @brief Represents an error for unsupported features. | |
136 | * | |
137 | * This error may occur due to the current configuration making a feature unavailable | |
138 | * (e.g. when using an older kernel or tracer release). | |
139 | */ | |
140 | class unsupported_error : public lttng::runtime_error { | |
b6bbb1d6 JG |
141 | public: |
142 | explicit unsupported_error(const std::string& msg, | |
9f4d1ef3 | 143 | const lttng::source_location& source_location); |
b6bbb1d6 JG |
144 | }; |
145 | ||
53cd1e22 | 146 | namespace ctl { |
62d6b5d0 | 147 | /* |
9f4d1ef3 JG |
148 | * @class error |
149 | * @brief Wraps lttng_error_code errors for reporting through liblttng-ctl's interface. | |
150 | * | |
151 | * There is typically a better way to report errors than using this type of exception. However, it | |
152 | * is sometimes useful to transition legacy code to use RAII facilities and exceptions without | |
153 | * revisiting every caller. | |
154 | */ | |
baac5795 | 155 | class error : public runtime_error { |
53cd1e22 | 156 | public: |
0038180d JG |
157 | explicit error(const std::string& msg, |
158 | lttng_error_code error_code, | |
9f4d1ef3 | 159 | const lttng::source_location& source_location); |
20f5a9ae JG |
160 | |
161 | lttng_error_code code() const noexcept | |
162 | { | |
163 | return _error_code; | |
164 | } | |
53cd1e22 JG |
165 | |
166 | private: | |
20f5a9ae | 167 | const lttng_error_code _error_code; |
53cd1e22 JG |
168 | }; |
169 | } /* namespace ctl */ | |
170 | ||
62d6b5d0 | 171 | /* |
9f4d1ef3 JG |
172 | * @class posix_error |
173 | * @brief Wraps a POSIX system error, including the location where the error occurred. | |
174 | */ | |
175 | class posix_error : public std::system_error, lttng::runtime_error { | |
53cd1e22 | 176 | public: |
baac5795 | 177 | explicit posix_error(const std::string& msg, |
9f4d1ef3 JG |
178 | unsigned int errno_code, |
179 | const lttng::source_location& source_location); | |
53cd1e22 JG |
180 | }; |
181 | ||
62d6b5d0 | 182 | /* |
9f4d1ef3 JG |
183 | * @class communication_error |
184 | * @brief Base class for communication errors between components. | |
185 | */ | |
186 | class communication_error : public lttng::runtime_error { | |
baac5795 JG |
187 | public: |
188 | explicit communication_error(const std::string& msg, | |
9f4d1ef3 | 189 | const lttng::source_location& source_location); |
baac5795 JG |
190 | }; |
191 | ||
62d6b5d0 | 192 | /* |
9f4d1ef3 JG |
193 | * @class protocol_error |
194 | * @brief Base class for protocol layer communication errors (encoding or decoding problems). | |
195 | */ | |
baac5795 JG |
196 | class protocol_error : public communication_error { |
197 | public: | |
198 | explicit protocol_error(const std::string& msg, | |
9f4d1ef3 | 199 | const lttng::source_location& source_location); |
baac5795 JG |
200 | }; |
201 | ||
62d6b5d0 | 202 | /* |
9f4d1ef3 JG |
203 | * @class invalid_argument_error |
204 | * @brief Represents an error for invalid arguments. | |
205 | */ | |
206 | class invalid_argument_error : public lttng::runtime_error { | |
aeeb48c6 | 207 | public: |
baac5795 | 208 | explicit invalid_argument_error(const std::string& msg, |
9f4d1ef3 | 209 | const lttng::source_location& source_location); |
aeeb48c6 JG |
210 | }; |
211 | ||
9f4d1ef3 JG |
212 | } /* namespace lttng */ |
213 | ||
214 | /* | |
215 | * Specialize fmt::formatter for lttng::source_location | |
216 | * | |
217 | * Due to a bug in g++ < 7.1, this specialization must be enclosed in the fmt namespace, | |
218 | * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480. | |
219 | */ | |
220 | namespace fmt { | |
221 | template <> | |
222 | struct formatter<lttng::source_location> : formatter<std::string> { | |
223 | template <typename FormatContextType> | |
224 | typename FormatContextType::iterator format(const lttng::source_location& location, | |
bd9231e4 | 225 | FormatContextType& ctx) const |
9f4d1ef3 JG |
226 | { |
227 | return format_to(ctx.out(), | |
228 | "{}() {}:{}", | |
229 | location.function_name.data(), | |
230 | location.file_name.data(), | |
231 | location.line_number); | |
232 | } | |
233 | }; | |
234 | } /* namespace fmt */ | |
53cd1e22 JG |
235 | |
236 | #endif /* LTTNG_EXCEPTION_H_ */ |