Restructure stack and context trace selection in DiagnosticInformation and document behavior

The logic for selecting the traces to print stays the same, but there
are fewer nested ifs now. This changes the format of the returned string
a bit by adding a heading for both traces.
This commit is contained in:
Julian Brost 2020-10-20 11:22:20 +02:00
parent 6104df37dc
commit 9aeb962863
2 changed files with 43 additions and 21 deletions

View File

@ -223,34 +223,37 @@ String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, boo
const auto *pex = dynamic_cast<const posix_error *>(&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<StackTraceErrorInfo>(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<ContextTraceErrorInfo>(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();

View File

@ -93,6 +93,25 @@ typedef boost::error_info<ContextTrace, ContextTrace> 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);