diff --git a/include/geode/basic/assert.hpp b/include/geode/basic/assert.hpp index d6104af23..9428ce027 100644 --- a/include/geode/basic/assert.hpp +++ b/include/geode/basic/assert.hpp @@ -30,7 +30,6 @@ #include #include -#include #include #include @@ -52,10 +51,6 @@ namespace geode */ class opengeode_basic_api OpenGeodeException : public std::runtime_error { - static constexpr int MAX_STACK_DEPTH = 10; - static constexpr int NB_SKIPPED_STACKS = 1; - static constexpr int SYMBOL_SIZE = 1024; - public: enum struct TYPE : std::uint8_t { @@ -65,10 +60,11 @@ namespace geode }; OpenGeodeException( OpenGeodeException&& ) = default; - OpenGeodeException( const OpenGeodeException& ) = delete; - OpenGeodeException& operator=( const OpenGeodeException& ) = delete; OpenGeodeException& operator=( OpenGeodeException&& ) = default; + OpenGeodeException& operator=( const OpenGeodeException& ); + OpenGeodeException( const OpenGeodeException& ); + ~OpenGeodeException() noexcept override; [[nodiscard]] TYPE type() const @@ -93,8 +89,6 @@ namespace geode return data_; } - [[nodiscard]] std::string stack_trace() const; - [[nodiscard]] bool has_parent() const { return parent_ != nullptr; @@ -107,8 +101,8 @@ namespace geode void set_parent( OpenGeodeException&& parent ) { - parent_ = - std::make_unique< OpenGeodeException >( std::move( parent ) ); + parent_ = std::make_unique< OpenGeodeException >( + std::forward< OpenGeodeException >( parent ) ); } [[nodiscard]] std::string string() const; @@ -126,11 +120,6 @@ namespace geode library_{ std::move( library ) }, data_{ std::move( data ) } { - stack_.fill( nullptr ); -#ifndef NDEBUG - stack_size_ = absl::GetStackTrace( - stack_.data(), MAX_STACK_DEPTH, NB_SKIPPED_STACKS ); -#endif } private: @@ -138,8 +127,6 @@ namespace geode std::string project_; std::string library_; std::any data_; - std::array< void*, MAX_STACK_DEPTH > stack_; - int stack_size_{ 0 }; std::unique_ptr< OpenGeodeException > parent_; }; @@ -152,5 +139,36 @@ namespace geode /*! * Catch all exceptions and rethrow an OpenGeodeException */ - void opengeode_basic_api throw_lippincott(); + template < typename Exception, typename... Args > + [[noreturn]] void throw_lippincott( + OpenGeodeException::TYPE type, const Args&... message ) + { + try + { + throw; + } + catch( OpenGeodeException& exception ) + { + Exception new_exception{ exception.data(), type, message... }; + new_exception.set_parent( std::move( exception ) ); + throw new_exception; + } + catch( const std::exception& exception ) + { + Exception new_exception{ nullptr, type, message... }; + Exception std_exception{ nullptr, + OpenGeodeException::TYPE::internal, + "std::exception: ", exception.what() }; + new_exception.set_parent( std::move( std_exception ) ); + throw new_exception; + } + catch( ... ) + { + Exception new_exception{ nullptr, type, message... }; + Exception unknown_exception{ nullptr, + OpenGeodeException::TYPE::internal, "Unknown exception" }; + new_exception.set_parent( std::move( unknown_exception ) ); + throw new_exception; + } + } } // namespace geode diff --git a/src/geode/basic/assert.cpp b/src/geode/basic/assert.cpp index b8b352edc..d1da5f1dc 100644 --- a/src/geode/basic/assert.cpp +++ b/src/geode/basic/assert.cpp @@ -25,13 +25,30 @@ #include -#include - #include #include namespace geode { + OpenGeodeException::OpenGeodeException( const OpenGeodeException& other ) + : std::runtime_error{ other }, + type_{ other.type_ }, + project_{ other.project_ }, + library_{ other.library_ }, + data_{ other.data_ }, + parent_{ other.parent_ ? std::make_unique< OpenGeodeException >( + *other.parent_ ) + : nullptr } + { + } + + OpenGeodeException& OpenGeodeException::operator=( + const OpenGeodeException& other ) + { + *this = OpenGeodeException{ other }; + return *this; + } + OpenGeodeException::~OpenGeodeException() noexcept = default; std::string_view OpenGeodeException::type_name() const @@ -51,31 +68,11 @@ namespace geode return "unknown"; } - std::string OpenGeodeException::stack_trace() const - { - std::string stack_string; - for( auto frame = 0; frame < stack_size_; ++frame ) - { - absl::StrAppend( &stack_string, " ", frame, ": " ); - if( std::array< char, SYMBOL_SIZE > symbol; absl::Symbolize( - stack_[frame], symbol.data(), sizeof( symbol ) ) ) - { - absl::StrAppend( &stack_string, symbol.data() ); - } - else - { - absl::StrAppend( &stack_string, "Unknown" ); - } - absl::StrAppend( &stack_string, "\n" ); - } - return stack_string; - } - std::string OpenGeodeException::string() const { return absl::StrCat( "OpenGeodeException of type ", type_name(), " from project ", project(), " and library ", library(), ": ", - what(), "\n", stack_trace() ); + what() ); } int geode_lippincott() @@ -105,27 +102,4 @@ namespace geode } return 1; } - - void throw_lippincott() - { - try - { - throw; - } - catch( const OpenGeodeException& /*unused*/ ) - { - throw; - } - catch( const std::exception& exception ) - { - throw OpenGeodeBasicException{ nullptr, - OpenGeodeException::TYPE::internal, "std::exception, ", - exception.what() }; - } - catch( ... ) - { - throw OpenGeodeBasicException{ nullptr, - OpenGeodeException::TYPE::internal, "Unknown exception" }; - } - } } // namespace geode