LCOV - code coverage report
Current view: top level - core - Error.cpp (source / functions) Hit Total Coverage
Test: test_coverage.info.cleaned Lines: 0 70 0.0 %
Date: 2022-08-04 03:43:28 Functions: 0 17 0.0 %

          Line data    Source code
       1             : #include "Error.h"
       2             : 
       3             : #include <sstream>
       4             : 
       5             : #include "Backtrace.h"
       6             : 
       7             : namespace elsa
       8             : {
       9             :     constexpr const char* runtime_error_message = "polymorphic elsa error, catch by reference!";
      10             : 
      11           0 :     Error::Error(std::string msg, bool generate_backtrace, bool store_cause)
      12           0 :         : std::runtime_error{runtime_error_message}, backtrace{nullptr}, msg{std::move(msg)}
      13             :     {
      14             : 
      15           0 :         if (generate_backtrace) {
      16           0 :             this->backtrace = std::make_shared<Backtrace>();
      17           0 :             this->backtrace->analyze();
      18             :         }
      19             : 
      20           0 :         if (store_cause) {
      21           0 :             this->storeCause();
      22             :         }
      23           0 :     }
      24             : 
      25           0 :     std::string Error::str() const { return this->msg; }
      26             : 
      27           0 :     const char* Error::what() const noexcept
      28             :     {
      29           0 :         this->what_cache = this->str();
      30           0 :         return this->what_cache.c_str();
      31             :     }
      32             : 
      33           0 :     void Error::storeCause()
      34             :     {
      35           0 :         if (not std::current_exception()) {
      36           0 :             return;
      37             :         }
      38             : 
      39             :         try {
      40           0 :             throw;
      41           0 :         } catch (Error& cause) {
      42           0 :             cause.trimBacktrace();
      43           0 :             this->cause = std::current_exception();
      44           0 :         } catch (...) {
      45           0 :             this->cause = std::current_exception();
      46           0 :         }
      47             :     }
      48             : 
      49           0 :     void Error::trimBacktrace()
      50             :     {
      51           0 :         if (this->backtrace) {
      52           0 :             this->backtrace->trimToCurrentStackFrame();
      53             :         }
      54           0 :     }
      55             : 
      56           0 :     void Error::rethrowCause() const
      57             :     {
      58           0 :         if (this->cause) {
      59           0 :             std::rethrow_exception(this->cause);
      60             :         }
      61           0 :     }
      62             : 
      63           0 :     std::string Error::typeName() const { return detail::symbolDemangle(typeid(*this).name()); }
      64             : 
      65           0 :     Backtrace* Error::getBacktrace() const { return this->backtrace.get(); }
      66             : 
      67           0 :     const std::string& Error::getMsg() const { return this->msg; }
      68             : 
      69           0 :     std::ostream& operator<<(std::ostream& os, const Error& e)
      70             :     {
      71             :         // output the exception cause
      72           0 :         bool had_a_cause = true;
      73             :         try {
      74           0 :             e.rethrowCause();
      75           0 :             had_a_cause = false;
      76           0 :         } catch (Error& cause) {
      77           0 :             os << cause << std::endl;
      78           0 :         } catch (std::exception& cause) {
      79           0 :             os << detail::symbolDemangle(typeid(cause).name()) << ": " << cause.what() << std::endl;
      80           0 :         }
      81             : 
      82           0 :         if (had_a_cause) {
      83           0 :             os << std::endl
      84             :                << "The above exception was the direct cause "
      85           0 :                   "of the following exception:"
      86           0 :                << std::endl
      87           0 :                << std::endl;
      88             :         }
      89             : 
      90             :         // output the exception backtrace
      91           0 :         auto* bt = e.getBacktrace();
      92           0 :         if (bt != nullptr) {
      93           0 :             os << *bt;
      94             :         } else {
      95           0 :             os << "origin:" << std::endl;
      96             :         }
      97             : 
      98           0 :         os << e.typeName() << ":" << std::endl;
      99           0 :         os << e.str();
     100             : 
     101           0 :         return os;
     102             :     }
     103             : 
     104             :     /**
     105             :      * Prints a backtrace_symbol object.
     106             :      */
     107           0 :     std::ostream& operator<<(std::ostream& os, const backtrace_symbol& bt_sym)
     108             :     {
     109             :         // imitate the looks of a Python traceback.
     110           0 :         os << " -> ";
     111             : 
     112           0 :         if (bt_sym.functionname.empty()) {
     113           0 :             os << '?';
     114             :         } else {
     115           0 :             os << bt_sym.functionname;
     116             :         }
     117             : 
     118           0 :         if (bt_sym.pc != nullptr) {
     119           0 :             os << " " << detail::addrToString(bt_sym.pc);
     120             :         }
     121             : 
     122           0 :         return os;
     123             :     }
     124             : 
     125             :     /**
     126             :      * Prints an entire Backtrace object.
     127             :      */
     128           0 :     std::ostream& operator<<(std::ostream& os, const Backtrace& bt)
     129             :     {
     130             :         // imitate the looks of a Python traceback.
     131           0 :         os << "Traceback (most recent call last):" << std::endl;
     132             : 
     133           0 :         bt.getSymbols([&os](const backtrace_symbol* symbol) { os << *symbol << std::endl; }, true);
     134             : 
     135           0 :         return os;
     136             :     }
     137             : 
     138           0 :     InternalError::InternalError(const std::string& msg) : Error{msg} {}
     139             : 
     140           0 :     LogicError::LogicError(const std::string& msg) : Error{msg} {}
     141             : 
     142           0 :     InvalidArgumentError::InvalidArgumentError(const std::string& msg) : Error{msg} {}
     143             : 
     144           0 :     BadCastError::BadCastError(const std::string& msg) : Error{msg} {}
     145             : 
     146             : } // namespace elsa

Generated by: LCOV version 1.14