Line data Source code
1 : #pragma once 2 : 3 : #include <exception> 4 : #include <memory> 5 : #include <stdexcept> 6 : #include <string> 7 : #include <sstream> 8 : 9 : #include "spdlog/fmt/fmt.h" 10 : 11 : namespace elsa 12 : { 13 : 14 : // fwd-decls for Backtrace.h 15 : struct backtrace_symbol; 16 : class Backtrace; 17 : 18 : /** 19 : * Base exception for every error that occurs in elsa. 20 : * 21 : * Usage: 22 : * try { 23 : * throw elsa::Error{"some info"}; 24 : * } 25 : * catch (elsa::Error &err) { 26 : * std::cout << "\x1b[31;1merror:\x1b[m\n" 27 : * << err << std::endl; 28 : * } 29 : * 30 : */ 31 : class Error : public std::runtime_error 32 : { 33 : public: 34 : template <typename FormatString, typename... Args> 35 : explicit Error(const FormatString& fmt, Args&&... args) 36 : : Error(fmt::format(fmt, std::forward<Args>(args)...)) 37 46 : { 38 46 : } 39 : 40 : Error(std::string msg, bool generate_backtrace = true, bool store_cause = true); 41 : 42 381 : ~Error() override = default; 43 : 44 : /** 45 : * String representation of this exception, as 46 : * specialized by a child exception. 47 : */ 48 : virtual std::string str() const; 49 : 50 : /** 51 : * Returns the message's content. 52 : */ 53 : const char* what() const noexcept override; 54 : 55 : /** 56 : * Stores a pointer to the currently-handled exception in this->cause. 57 : */ 58 : void storeCause(); 59 : 60 : /** 61 : * Calls this->backtrace->trimToCurrentStackFrame(), 62 : * if this->backtrace is not nullptr. 63 : * 64 : * Designed to be used in catch clauses, to strip away all those 65 : * unneeded symbols from program init upwards. 66 : */ 67 : void trimBacktrace(); 68 : 69 : /** 70 : * Re-throws the exception cause, if the exception has one. 71 : * Otherwise, does nothing. 72 : * 73 : * Use this when handling the exception, to handle the cause. 74 : */ 75 : void rethrowCause() const; 76 : 77 : /** 78 : * Get the type name of of the exception. 79 : * Use it to display the name of a child exception. 80 : */ 81 : virtual std::string typeName() const; 82 : 83 : /** 84 : * Return the backtrace where the exception was thrown. 85 : * nullptr if no backtrace was collected. 86 : */ 87 : Backtrace* getBacktrace() const; 88 : 89 : /** 90 : * Directly return the message stored in the exception. 91 : */ 92 : const std::string& getMsg() const; 93 : 94 : protected: 95 : /** 96 : * The (optional) backtrace where the exception came from. 97 : */ 98 : std::shared_ptr<Backtrace> backtrace; 99 : 100 : /** 101 : * The error message text. 102 : */ 103 : std::string msg; 104 : 105 : /** 106 : * Cached error message text for returning C string via what(). 107 : */ 108 : mutable std::string what_cache; 109 : 110 : /** 111 : * Re-throw this with rethrowCause(). 112 : */ 113 : std::exception_ptr cause; 114 : }; 115 : 116 : /** 117 : * Output stream concat for Errors. 118 : */ 119 : std::ostream& operator<<(std::ostream& os, const Error& e); 120 : 121 : /** 122 : * Output stream concat for backtrace symbols. 123 : */ 124 : std::ostream& operator<<(std::ostream& os, const backtrace_symbol& bt_sym); 125 : 126 : /** 127 : * Output stream concat for backtraces. 128 : */ 129 : std::ostream& operator<<(std::ostream& os, const Backtrace& bt); 130 : 131 : /** 132 : * Internal Error, thrown when some interal sanity check failed. 133 : */ 134 : class InternalError : public Error 135 : { 136 : public: 137 : InternalError(const std::string& msg); 138 : }; 139 : 140 : /** 141 : * Faulty logic due to violation of expected preconditions. 142 : */ 143 : class LogicError : public Error 144 : { 145 : public: 146 : LogicError(const std::string& msg); 147 : }; 148 : 149 : /** 150 : * User gave something wrong to our function. 151 : */ 152 : class InvalidArgumentError : public Error 153 : { 154 : public: 155 : InvalidArgumentError(const std::string& msg); 156 : }; 157 : 158 : /** 159 : * Could not cast to the given type 160 : */ 161 : class BadCastError : public Error 162 : { 163 : public: 164 : BadCastError(const std::string& msg); 165 : }; 166 : 167 : /** 168 : * The function is not implemented 169 : */ 170 : class NotImplementedError : public Error 171 : { 172 : public: 173 : NotImplementedError(const std::string& msg); 174 : }; 175 : 176 : } // namespace elsa