diff --git a/src/util.h b/src/util.h index 3b54286b3baf2..a54655052d3ad 100644 --- a/src/util.h +++ b/src/util.h @@ -71,6 +71,9 @@ int LogPrintStr(const std::string& str); #define LogPrintf(...) LogPrint(NULL, __VA_ARGS__) +/** Get format string from VA_ARGS for error reporting */ +template std::string FormatStringFromLogArgs(const char *fmt, const Args&... args) { return fmt; } + /** * When we switch to C++11, this can be switched to variadic templates instead * of this macro-based construction (see tinyformat.h). @@ -81,13 +84,25 @@ int LogPrintStr(const std::string& str); static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \ { \ if (!LogAcceptCategory(category)) return 0; \ - return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \ + std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \ + try { \ + _log_msg_ = tfm::format(format, TINYFORMAT_PASSARGS(n)); \ + } catch (std::runtime_error &e) { \ + _log_msg_ = "Error \"" + std::string(e.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(format, TINYFORMAT_PASSARGS(n));\ + } \ + return LogPrintStr(_log_msg_); \ } \ /** Log error and return false */ \ template \ static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \ { \ - LogPrintStr(std::string("ERROR: ") + tfm::format(format, TINYFORMAT_PASSARGS(n)) + "\n"); \ + std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \ + try { \ + _log_msg_ = tfm::format(format, TINYFORMAT_PASSARGS(n)); \ + } catch (std::runtime_error &e) { \ + _log_msg_ = "Error \"" + std::string(e.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(format, TINYFORMAT_PASSARGS(n));\ + } \ + LogPrintStr(std::string("ERROR: ") + _log_msg_ + "\n"); \ return false; \ }