RTC Toolkit 4.0.1
Loading...
Searching...
No Matches
exceptions.hpp
Go to the documentation of this file.
1
13#ifndef RTCTK_COMPONENTFRAMEWORK_EXCEPTIONS_HPP
14#define RTCTK_COMPONENTFRAMEWORK_EXCEPTIONS_HPP
15
16#include <string_view>
17#include <type_traits>
18#include <typeinfo>
19
20#include <ciiBasicDataType.hpp>
21#include <ciiException.hpp>
22
23namespace {
24
25// Constructs an exception object. Depending on the type of the exception, additional context
26// information is added to the object if supported.
27// This function is used to implement the CII_THROW and CII_THROW_WITH_NESTED macros.
28template <typename T, typename N, typename... Args>
29T CreateExceptionObject(
30 const N& nested_exception, const char* file, int line, const char* function, Args&&... args) {
31 if constexpr (std::is_base_of_v<elt::error::CiiException, T>) {
32 T throwing_exception = T(std::forward<Args>(args)...);
33 throwing_exception.SetFileName(boost::filesystem::path(file).filename().string());
34 throwing_exception.SetFunctionName(function);
35 throwing_exception.SetLineNumber(line);
36 throwing_exception.SetClassName(boost::core::demangle(typeid(T).name()));
37 std::vector<std::string> this_stack;
38 this_stack.push_back(throwing_exception.getCiiMessage());
39 if constexpr (std::is_base_of_v<elt::error::CiiException, N>) {
40 std::vector<std::string> nested_stack = nested_exception.getCiiExceptionStack();
41 this_stack.insert(this_stack.end(), nested_stack.begin(), nested_stack.end());
42 } else if constexpr (std::is_base_of_v<std::exception, N>) {
43 this_stack.push_back(nested_exception.what());
44 } else {
45 this_stack.push_back("Unknown exception.");
46 }
47 throwing_exception.SetCiiExceptionStack(this_stack);
48 return throwing_exception;
49 } else {
50 return T(std::forward<Args>(args)...);
51 }
52}
53
54} // namespace
55
56// We temporarily redefine the CII_THROW_WITH_NESTED macro to be backwards compatible with
57// std::runtime_error and std::logic_error, i.e. to still support these as nested exception.
58// TODO: Remove the redefinitions once CII allows std::exceptions for nested exceptions.
59
60#ifdef CII_THROW_WITH_NESTED
61#undef CII_THROW_WITH_NESTED
62
63#define CII_THROW_WITH_NESTED(exceptionType_t, nested_exception, ...) \
64 { \
65 exceptionType_t throwing_exception = CreateExceptionObject<exceptionType_t>( \
66 nested_exception, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__); \
67 std::throw_with_nested(throwing_exception); \
68 }
69
70#endif // CII_THROW_WITH_NESTED
71
73namespace detail {
74
82template <class T>
83struct UnspecifiedNested : virtual T, virtual std::nested_exception {
84 template <class E>
85 explicit UnspecifiedNested(E&& e) noexcept(std::is_nothrow_constructible_v<T, E&&>)
86 : T(std::forward<E>(e)) {
87 }
88};
89
95std::ostream& JoinLines(std::ostream& os,
96 std::string_view lines,
97 std::string_view initial_indent,
98 std::string_view subsequent_indent);
99
100} // namespace detail
101
120template <class E>
121auto WrapWithNested(E&& exception) noexcept(
122 std::is_nothrow_constructible_v<detail::UnspecifiedNested<typename std::decay_t<E>>, E&&>) {
123 using Type = typename std::decay_t<E>;
124 static_assert(std::is_class_v<Type>, "exception must be a non-union class-type");
125
126 return detail::UnspecifiedNested<Type>(std::forward<E>(exception));
127}
128
143void PrintComposedExceptions(std::ostream& os, std::vector<std::exception_ptr> const& exceptions);
144
159void PrintNestedExceptions(std::ostream& os, std::exception const& exception);
160
171void PrintNestedExceptions(std::ostream& os, std::exception_ptr ptr);
172
186public:
190 explicit NestedExceptionPrinter(std::exception const& exception) noexcept
191 : m_ptr(), m_exception(&exception){};
195 explicit NestedExceptionPrinter(std::exception_ptr ptr) noexcept
196 : m_ptr(std::move(ptr)), m_exception(nullptr){};
197
203 std::string Str() const {
204 std::stringstream ss;
205 ss << *this;
206 return ss.str();
207 }
208
216 friend std::ostream& operator<<(std::ostream& os, NestedExceptionPrinter const& printer) {
217 if (printer.m_ptr) {
218 PrintNestedExceptions(os, printer.m_ptr);
219 } else if (printer.m_exception) {
220 PrintNestedExceptions(os, *printer.m_exception);
221 }
222 return os;
223 }
224
225private:
226 // A variant or union would occupy same space so this was preferred over
227 // including <variant>
228 std::exception_ptr m_ptr;
229 std::exception const* m_exception;
230};
231
237class RtctkException : public elt::error::CiiBaseException {
238public:
239 RtctkException() noexcept;
240
241 explicit RtctkException(const std::string& msg);
242
243 RtctkException(const RtctkException& other) noexcept;
244
245 virtual ~RtctkException() override = default;
246};
247
255public:
256 explicit NotImplementedException(const std::string& feature);
257};
258
266public:
267 explicit UnsupportedTypeException(const std::string& type);
268 explicit UnsupportedTypeException(const std::type_info& type);
269 explicit UnsupportedTypeException(const elt::common::CiiBasicDataType type);
270};
271
279public:
280 explicit UnsupportedUriException(const elt::mal::Uri& uri);
281 explicit UnsupportedUriException(const std::string& context, const elt::mal::Uri& uri);
282};
283
291public:
292 explicit BufferTooSmall(const std::size_t actual, const std::size_t expected);
293 std::size_t GetActualBufferSize() const {
294 return m_actual;
295 }
296 std::size_t GetExpectedBufferSize() const {
297 return m_expected;
298 }
299
300protected:
301 std::size_t m_actual;
302 std::size_t m_expected;
303};
304
311public:
312 explicit InvalidArgumentException(const std::string& message);
313};
314
324public:
325 explicit InitialisationException(const std::string& message);
326};
327
335public:
337 explicit InvalidStateChange(const std::string& message)
338 : RtctkException("Invalid Operation: " + message) {
339 }
340};
341
349public:
351 explicit InvalidSetting(const std::string& message)
352 : RtctkException("Invalid Setting: " + message) {
353 }
354};
355
363public:
365 explicit DdtSinkNotFound(const std::string& message)
366 : RtctkException("DDT Sink not found: " + message) {
367 }
368};
369
377class DdtError : public RtctkException {
378public:
380 explicit DdtError(const std::string& message)
381 : RtctkException("Error in DDT Publisher: " + message) {
382 }
383};
384
392class IpcqError : public RtctkException {
393public:
395 explicit IpcqError(const std::string& message) : RtctkException("Error in IPCQ: " + message) {
396 }
397};
398
406public:
407 explicit AdapterCreationException(const std::string& interface_name);
408};
409
410} // namespace rtctk::componentFramework
411
412#endif // RTCTK_COMPONENTFRAMEWORK_EXCEPTIONS_HPP
Thrown from service factory methods to indicate the adapter construction failed.
Definition: exceptions.hpp:405
The BufferTooSmall is thrown when an API call fails because the provided buffer is not big enough to ...
Definition: exceptions.hpp:290
std::size_t m_actual
Definition: exceptions.hpp:301
std::size_t GetActualBufferSize() const
Definition: exceptions.hpp:293
std::size_t m_expected
Definition: exceptions.hpp:302
std::size_t GetExpectedBufferSize() const
Definition: exceptions.hpp:296
This Exception is raised when the DDT Publisher returns an error that cannot be handled by the DDT Si...
Definition: exceptions.hpp:377
DdtError(const std::string &message)
Definition: exceptions.hpp:380
This Exception is raised when an invalid ddt sink is requested.
Definition: exceptions.hpp:362
DdtSinkNotFound(const std::string &message)
Definition: exceptions.hpp:365
Thrown in cases where an initialisation routine has failed.
Definition: exceptions.hpp:323
Thrown if an argument passed to a method was invalid.
Definition: exceptions.hpp:310
This Exception is raised when a invalid setting was used in the runtime repo.
Definition: exceptions.hpp:348
InvalidSetting(const std::string &message)
Definition: exceptions.hpp:351
This Exception is raised when the state change requested is invalid.
Definition: exceptions.hpp:334
InvalidStateChange(const std::string &message)
Definition: exceptions.hpp:337
This Exception is raised when the ipc queue returns an error that cannot be handled by the Telemetry ...
Definition: exceptions.hpp:392
IpcqError(const std::string &message)
Definition: exceptions.hpp:395
Adapter object intended to be used in contexts without direct access to the output-stream object.
Definition: exceptions.hpp:185
friend std::ostream & operator<<(std::ostream &os, NestedExceptionPrinter const &printer)
Formats exception from printer using PrintNestedExceptions.
Definition: exceptions.hpp:216
std::string Str() const
Convenience function for constructing a std::string from the exception.
Definition: exceptions.hpp:203
NestedExceptionPrinter(std::exception_ptr ptr) noexcept
Construct from exception_ptr.
Definition: exceptions.hpp:195
NestedExceptionPrinter(std::exception const &exception) noexcept
Construct from exception derived from std::exception.
Definition: exceptions.hpp:190
The NotImplementedException is thrown whenever an attempt is made to use a feature or function that h...
Definition: exceptions.hpp:254
The RtctkException class is the base class for all Rtctk exceptions.
Definition: exceptions.hpp:237
RtctkException() noexcept
Definition: exceptions.cpp:113
virtual ~RtctkException() override=default
The UnsupportedTypeException is thrown whenever an attempt is made to use an unsupported type in the ...
Definition: exceptions.hpp:265
The UnsupportedUriException is thrown whenever an attempt is made to use an unsupported URI in the RT...
Definition: exceptions.hpp:278
auto WrapWithNested(E &&exception) noexcept(std::is_nothrow_constructible_v< detail::UnspecifiedNested< typename std::decay_t< E > >, E && >)
Constructs an unspecified exception that derives from both the provided object and std::nested_except...
Definition: exceptions.hpp:121
void PrintNestedExceptions(std::ostream &os, std::exception const &exception)
Print nested exception(s) in exception messages to os.
Definition: exceptions.cpp:201
void PrintComposedExceptions(std::ostream &os, std::vector< std::exception_ptr > const &exceptions)
Print composed exception(s) in exception messages to os.
Definition: exceptions.cpp:186
std::ostream & JoinLines(std::ostream &os, std::string_view lines, std::string_view initial_indent, std::string_view subsequent_indent)
Join each line in lines with.
Definition: exceptions.cpp:26
Definition: commandReplier.cpp:22
name
Definition: wscript:36
Unspecified exception used by WrapWithNested.
Definition: exceptions.hpp:83
UnspecifiedNested(E &&e) noexcept(std::is_nothrow_constructible_v< T, E && >)
Definition: exceptions.hpp:85