From cc1e9c05ec242f7137a0680fa9a507f0b8af0d91 Mon Sep 17 00:00:00 2001 From: Julian Brost Date: Mon, 18 Jul 2022 15:12:23 +0200 Subject: [PATCH] Windows: output useful error message for syscall errors --- lib/base/exception.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ lib/base/exception.hpp | 7 ++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/base/exception.cpp b/lib/base/exception.cpp index a194dafd5..57b324b4a 100644 --- a/lib/base/exception.cpp +++ b/lib/base/exception.cpp @@ -180,6 +180,13 @@ String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, boo String message = ex.what(); +#ifdef _WIN32 + const auto *win32_err = dynamic_cast(&ex); + if (win32_err) { + message = to_string(*win32_err); + } +#endif /* _WIN32 */ + const auto *vex = dynamic_cast(&ex); if (message.IsEmpty()) @@ -424,6 +431,39 @@ std::string icinga::to_string(const StackTraceErrorInfo&) } #ifdef _WIN32 +const char *win32_error::what() const noexcept +{ + return "win32_error"; +} + +std::string icinga::to_string(const win32_error &e) { + std::ostringstream msgbuf; + + const char * const *func = boost::get_error_info(e); + + if (func) { + msgbuf << "Function call '" << *func << "'"; + } else { + msgbuf << "Function call"; + } + + const std::string *fname = boost::get_error_info(e); + + if (fname) { + msgbuf << " for file '" << *fname << "'"; + } + + msgbuf << " failed"; + + const int *errnum = boost::get_error_info(e); + + if (errnum) { + msgbuf << " with error code " << Utility::FormatErrorNumber(*errnum); + } + + return msgbuf.str(); +} + std::string icinga::to_string(const errinfo_win32_error& e) { return "[errinfo_win32_error] = " + Utility::FormatErrorNumber(e.value()) + "\n"; diff --git a/lib/base/exception.hpp b/lib/base/exception.hpp index c18bd7abe..18dab650e 100644 --- a/lib/base/exception.hpp +++ b/lib/base/exception.hpp @@ -127,7 +127,12 @@ private: }; #ifdef _WIN32 -class win32_error : virtual public std::exception, virtual public boost::exception { }; +class win32_error : virtual public std::exception, virtual public boost::exception { +public: + const char *what() const noexcept override; +}; + +std::string to_string(const win32_error& e); struct errinfo_win32_error_; typedef boost::error_info errinfo_win32_error;