From 74ed6afc0a139ad090d27951a85fad6502d4f419 Mon Sep 17 00:00:00 2001 From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> Date: Mon, 6 May 2024 23:01:11 -0500 Subject: [PATCH] Add cpptrace::system_error --- README.md | 13 ++++++++++++- include/cpptrace/cpptrace.hpp | 12 ++++++++++++ src/cpptrace.cpp | 11 +++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 01de41b..5f04283 100644 --- a/README.md +++ b/README.md @@ -348,6 +348,8 @@ Cpptrace provides an interface for a traced exceptions, `cpptrace::exception`, a that that generate stack traces when thrown. These exceptions generate relatively lightweight raw traces and resolve symbols and line numbers lazily if and when requested. +These are provided both as a useful utility and as a reference implementation for traced exceptions. + The basic interface is: ```cpp namespace cpptrace { @@ -398,7 +400,7 @@ namespace cpptrace { const char* message() const noexcept override; }; - // All stdexcept errors have analogs here. All have the constructor: + // All stdexcept errors have analogs here. All but system_error have the constructor: // explicit the_error( // std::string&& message_arg, // raw_trace&& trace = detail::get_raw_trace_and_absorb() @@ -413,6 +415,15 @@ namespace cpptrace { class range_error : public exception_with_message { ... }; class overflow_error : public exception_with_message { ... }; class underflow_error : public exception_with_message { ... }; + class system_error : public runtime_error { + public: + explicit system_error( + int error_code, + std::string&& message_arg, + raw_trace&& trace = detail::get_raw_trace_and_absorb() + ) noexcept; + const std::error_code& code() const noexcept; + }; } ``` diff --git a/include/cpptrace/cpptrace.hpp b/include/cpptrace/cpptrace.hpp index e47e785..6fd465a 100644 --- a/include/cpptrace/cpptrace.hpp +++ b/include/cpptrace/cpptrace.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -437,6 +438,17 @@ namespace cpptrace { std::exception_ptr nested_ptr() const noexcept; }; + class CPPTRACE_EXPORT system_error : public runtime_error { + std::error_code ec; + public: + explicit system_error( + int error_code, + std::string&& message_arg, + raw_trace&& trace = detail::get_raw_trace_and_absorb() + ) noexcept; + const std::error_code& code() const noexcept; + }; + // [[noreturn]] must come first due to old clang [[noreturn]] CPPTRACE_EXPORT void rethrow_and_wrap_if_needed(std::size_t skip = 0); } diff --git a/src/cpptrace.cpp b/src/cpptrace.cpp index bc1390b..b104ff4 100644 --- a/src/cpptrace.cpp +++ b/src/cpptrace.cpp @@ -577,6 +577,17 @@ namespace cpptrace { return user_message.c_str(); } + system_error::system_error(int error_code, std::string&& message_arg, raw_trace&& trace) noexcept + : runtime_error( + message_arg + ": " + std::error_code(error_code, std::generic_category()).message(), + std::move(trace) + ), + ec(std::error_code(error_code, std::generic_category())) {} + + const std::error_code& system_error::code() const noexcept { + return ec; + } + const char* nested_exception::message() const noexcept { if(message_value.empty()) { try {