1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ 2 3 #ifndef EXCEPTION_H 4 #define EXCEPTION_H 5 6 #include "base/i2-base.hpp" 7 #include "base/string.hpp" 8 #include "base/context.hpp" 9 #include "base/debuginfo.hpp" 10 #include "base/dictionary.hpp" 11 #include "base/configobject.hpp" 12 #include <boost/exception/errinfo_api_function.hpp> 13 #include <boost/exception/errinfo_errno.hpp> 14 #include <boost/exception/errinfo_file_name.hpp> 15 #include <boost/exception/diagnostic_information.hpp> 16 #include <boost/exception_ptr.hpp> 17 #include <boost/stacktrace.hpp> 18 19 #ifdef _WIN32 20 # include <boost/algorithm/string/trim.hpp> 21 #endif /* _WIN32 */ 22 23 namespace icinga 24 { 25 26 class user_error : virtual public std::exception, virtual public boost::exception 27 { }; 28 29 /* 30 * @ingroup base 31 */ 32 class ScriptError : virtual public user_error 33 { 34 public: 35 ScriptError(String message); 36 ScriptError(String message, DebugInfo di, bool incompleteExpr = false); 37 38 const char *what(void) const throw() final; 39 40 DebugInfo GetDebugInfo() const; 41 bool IsIncompleteExpression() const; 42 43 bool IsHandledByDebugger() const; 44 void SetHandledByDebugger(bool handled); 45 46 private: 47 String m_Message; 48 DebugInfo m_DebugInfo; 49 bool m_IncompleteExpr; 50 bool m_HandledByDebugger; 51 }; 52 53 /* 54 * @ingroup base 55 */ 56 class ValidationError : virtual public user_error 57 { 58 public: 59 ValidationError(const ConfigObject::Ptr& object, const std::vector<String>& attributePath, const String& message); 60 ~ValidationError() throw() override; 61 62 const char *what() const throw() override; 63 64 ConfigObject::Ptr GetObject() const; 65 std::vector<String> GetAttributePath() const; 66 String GetMessage() const; 67 68 void SetDebugHint(const Dictionary::Ptr& dhint); 69 Dictionary::Ptr GetDebugHint() const; 70 71 private: 72 ConfigObject::Ptr m_Object; 73 std::vector<String> m_AttributePath; 74 String m_Message; 75 String m_What; 76 Dictionary::Ptr m_DebugHint; 77 }; 78 79 boost::stacktrace::stacktrace *GetLastExceptionStack(); 80 void SetLastExceptionStack(const boost::stacktrace::stacktrace& trace); 81 82 ContextTrace *GetLastExceptionContext(); 83 void SetLastExceptionContext(const ContextTrace& context); 84 85 void RethrowUncaughtException(); 86 87 struct errinfo_stacktrace_; 88 typedef boost::error_info<struct errinfo_stacktrace_, boost::stacktrace::stacktrace> StackTraceErrorInfo; 89 90 std::string to_string(const StackTraceErrorInfo&); 91 92 typedef boost::error_info<ContextTrace, ContextTrace> ContextTraceErrorInfo; 93 94 std::string to_string(const ContextTraceErrorInfo& e); 95 96 /** 97 * Generate diagnostic information about an exception 98 * 99 * The following information is gathered in the result: 100 * - Exception error message 101 * - Debug information about the Icinga config if the exception is a ValidationError 102 * - Stack trace 103 * - Context trace 104 * 105 * Each, stack trace and the context trace, are printed if the they were saved in the boost exception error 106 * information, are explicitly passed as a parameter, or were stored when the last exception was thrown. If multiple 107 * of these exist, the first one is used. 108 * 109 * @param ex exception to print diagnostic information about 110 * @param verbose if verbose is set, a stack trace is added 111 * @param stack optionally supply a stack trace 112 * @param context optionally supply a context trace 113 * @return string containing the aforementioned information 114 */ 115 String DiagnosticInformation(const std::exception& ex, bool verbose = true, 116 boost::stacktrace::stacktrace *stack = nullptr, ContextTrace *context = nullptr); 117 String DiagnosticInformation(const boost::exception_ptr& eptr, bool verbose = true); 118 119 class posix_error : virtual public std::exception, virtual public boost::exception { 120 public: 121 ~posix_error() throw() override; 122 123 const char *what(void) const throw() final; 124 125 private: 126 mutable char *m_Message{nullptr}; 127 }; 128 129 #ifdef _WIN32 130 class win32_error : virtual public std::exception, virtual public boost::exception { }; 131 132 struct errinfo_win32_error_; 133 typedef boost::error_info<struct errinfo_win32_error_, int> errinfo_win32_error; 134 135 std::string to_string(const errinfo_win32_error& e); 136 #endif /* _WIN32 */ 137 138 struct errinfo_getaddrinfo_error_; 139 typedef boost::error_info<struct errinfo_getaddrinfo_error_, int> errinfo_getaddrinfo_error; 140 141 std::string to_string(const errinfo_getaddrinfo_error& e); 142 143 struct errinfo_message_; 144 typedef boost::error_info<struct errinfo_message_, std::string> errinfo_message; 145 146 class invalid_downtime_removal_error : virtual public std::exception, virtual public boost::exception { 147 public: 148 explicit invalid_downtime_removal_error(String message); 149 explicit invalid_downtime_removal_error(const char* message); 150 151 ~invalid_downtime_removal_error() noexcept override; 152 153 const char *what() const noexcept final; 154 155 private: 156 String m_Message; 157 }; 158 159 } 160 161 #endif /* EXCEPTION_H */ 162