diff --git a/lib/base/exception.cpp b/lib/base/exception.cpp index 5ab24cec0..c6e485483 100644 --- a/lib/base/exception.cpp +++ b/lib/base/exception.cpp @@ -223,34 +223,37 @@ String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, boo const auto *pex = dynamic_cast(&ex); if (!uex && !pex && verbose) { + // Print the first of the following stack traces (if any exists) + // 1. stack trace from boost exception error information const boost::stacktrace::stacktrace *st = boost::get_error_info(ex); + // 2. stack trace explicitly passed as a parameter + if (!st) { + st = stack; + } + // 3. stack trace saved when the last exception was thrown + if (!st) { + st = GetLastExceptionStack(); + } - if (st) { - result << *st; - } else { - result << std::endl; - - if (!stack) - stack = GetLastExceptionStack(); - - if (stack) - result << *stack; - + if (st && !st->empty()) { + result << "\nStacktrace:\n" << *st; } } + // Print the first of the following context traces (if any exists) + // 1. context trace from boost exception error information const ContextTrace *ct = boost::get_error_info(ex); + // 2. context trace explicitly passed as a parameter + if (!ct) { + ct = context; + } + // 3. context trace saved when the last exception was thrown + if (!ct) { + ct = GetLastExceptionContext(); + } - if (ct) { - result << *ct; - } else { - result << std::endl; - - if (!context) - context = GetLastExceptionContext(); - - if (context) - result << *context; + if (ct && ct->GetLength() > 0) { + result << "\nContext:\n" << *ct; } return result.str(); diff --git a/lib/base/exception.hpp b/lib/base/exception.hpp index 10e2b4d0b..279b1d036 100644 --- a/lib/base/exception.hpp +++ b/lib/base/exception.hpp @@ -93,6 +93,25 @@ typedef boost::error_info ContextTraceErrorInfo; std::string to_string(const ContextTraceErrorInfo& e); +/** + * Generate diagnostic information about an exception + * + * The following information is gathered in the result: + * - Exception error message + * - Debug information about the Icinga config if the exception is a ValidationError + * - Stack trace + * - Context trace + * + * Each, stack trace and the context trace, are printed if the they were saved in the boost exception error + * information, are explicitly passed as a parameter, or were stored when the last exception was thrown. If multiple + * of these exist, the first one is used. + * + * @param ex exception to print diagnostic information about + * @param verbose if verbose is set, a stack trace is added + * @param stack optionally supply a stack trace + * @param context optionally supply a context trace + * @return string containing the aforementioned information + */ String DiagnosticInformation(const std::exception& ex, bool verbose = true, boost::stacktrace::stacktrace *stack = nullptr, ContextTrace *context = nullptr); String DiagnosticInformation(const boost::exception_ptr& eptr, bool verbose = true);