Add exception wrapping utilities, will help issues like #60
This commit is contained in:
parent
61d536bc02
commit
ab7e71f1b2
@ -244,7 +244,7 @@ namespace cpptrace {
|
|||||||
protected:
|
protected:
|
||||||
explicit exception_with_message(
|
explicit exception_with_message(
|
||||||
std::string&& message_arg,
|
std::string&& message_arg,
|
||||||
std::uint32_t skip
|
std::size_t skip
|
||||||
) noexcept : exception(skip + 1), message(std::move(message_arg)) {}
|
) noexcept : exception(skip + 1), message(std::move(message_arg)) {}
|
||||||
|
|
||||||
explicit exception_with_message(
|
explicit exception_with_message(
|
||||||
@ -313,6 +313,21 @@ namespace cpptrace {
|
|||||||
explicit underflow_error(std::string&& message_arg) noexcept
|
explicit underflow_error(std::string&& message_arg) noexcept
|
||||||
: exception_with_message(std::move(message_arg), 1) {}
|
: exception_with_message(std::move(message_arg), 1) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CPPTRACE_EXPORT nested_exception : public exception {
|
||||||
|
std::exception_ptr ptr;
|
||||||
|
mutable std::string what_value;
|
||||||
|
public:
|
||||||
|
explicit nested_exception(std::exception_ptr exception_ptr) noexcept
|
||||||
|
: exception(1), ptr(exception_ptr) {}
|
||||||
|
explicit nested_exception(std::exception_ptr exception_ptr, std::size_t skip) noexcept
|
||||||
|
: exception(skip + 1), ptr(exception_ptr) {}
|
||||||
|
|
||||||
|
const char* get_raw_what() const noexcept override;
|
||||||
|
std::exception_ptr nested_ptr() const noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
CPPTRACE_EXPORT [[noreturn]] void rethrow_and_wrap_if_needed(std::size_t skip = 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CPPTRACE_STD_FORMAT) && defined(__cpp_lib_format)
|
#if defined(CPPTRACE_STD_FORMAT) && defined(__cpp_lib_format)
|
||||||
@ -331,4 +346,21 @@ namespace cpptrace {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Exception wrapper utilities
|
||||||
|
#define CPPTRACE_WRAP_BLOCK(statements) do { \
|
||||||
|
try { \
|
||||||
|
statements \
|
||||||
|
} catch(...) { \
|
||||||
|
::cpptrace::rethrow_and_wrap_if_needed(); \
|
||||||
|
} \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
#define CPPTRACE_WRAP(expression) [&] () -> decltype((expression)) { \
|
||||||
|
try { \
|
||||||
|
return expression; \
|
||||||
|
} catch(...) { \
|
||||||
|
::cpptrace::rethrow_and_wrap_if_needed(1); \
|
||||||
|
} \
|
||||||
|
} ()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -362,6 +362,7 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void terminate_handler() {
|
[[noreturn]] void terminate_handler() {
|
||||||
|
// TODO: Support std::nested_exception?
|
||||||
try {
|
try {
|
||||||
auto ptr = std::current_exception();
|
auto ptr = std::current_exception();
|
||||||
if(ptr == nullptr) {
|
if(ptr == nullptr) {
|
||||||
@ -486,4 +487,32 @@ namespace cpptrace {
|
|||||||
const char* exception_with_message::get_raw_what() const noexcept {
|
const char* exception_with_message::get_raw_what() const noexcept {
|
||||||
return message.c_str();
|
return message.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* nested_exception::get_raw_what() const noexcept {
|
||||||
|
if(what_value.empty()) {
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(ptr);
|
||||||
|
} catch(std::exception& e) {
|
||||||
|
// what_value = std::string("cpptrace::nested_exception: ") + e.what();
|
||||||
|
what_value = e.what();
|
||||||
|
} catch(...) {
|
||||||
|
what_value = "<cpptrace::nested_exception holding instance of " + detail::exception_type_name() + ">";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return what_value.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::exception_ptr nested_exception::nested_ptr() const noexcept {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rethrow_and_wrap_if_needed(std::size_t skip) {
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(std::current_exception());
|
||||||
|
} catch(cpptrace::exception&) {
|
||||||
|
throw; // already a cpptrace::exception
|
||||||
|
} catch(...) {
|
||||||
|
throw nested_exception(std::current_exception(), skip + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user