From 0032d1f5fa23364d412f2be426e17bbe44a7d97f Mon Sep 17 00:00:00 2001 From: HÃ¥vard Pettersen Date: Mon, 11 Oct 2021 10:54:06 +0000 Subject: add more convenient issue reporting --- vespalib/src/tests/issue/issue_test.cpp | 19 +++++++++++++++++++ vespalib/src/vespa/vespalib/util/issue.cpp | 29 ++++++++++++++++++++++++++--- vespalib/src/vespa/vespalib/util/issue.h | 12 ++++++++++-- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/vespalib/src/tests/issue/issue_test.cpp b/vespalib/src/tests/issue/issue_test.cpp index 01b151da482..4799e032da2 100644 --- a/vespalib/src/tests/issue/issue_test.cpp +++ b/vespalib/src/tests/issue/issue_test.cpp @@ -12,6 +12,12 @@ struct MyHandler : Issue::Handler { } }; +struct MyException : std::exception { + vespalib::string my_what; + MyException(vespalib::string what_in) : my_what(what_in) {} + const char *what() const noexcept override { return my_what.c_str(); } +}; + std::vector make_list(std::vector list) { return list; } @@ -65,4 +71,17 @@ TEST(IssueTest, handler_can_be_bound_multiple_times) { EXPECT_EQ(my_handler.list, make_list({"issue1", "issue2", "issue3"})); } +TEST(IssueTest, alternative_report_functions) { + MyHandler my_handler; + auto capture = Issue::listen(my_handler); + Issue::report(vespalib::string("str")); + Issue::report("fmt_%s_%d", "msg", 7); + try { + throw MyException("exception"); + } catch (const std::exception &e) { + Issue::report(e); + } + EXPECT_EQ(my_handler.list, make_list({"str", "fmt_msg_7", "exception"})); +} + GTEST_MAIN_RUN_ALL_TESTS() diff --git a/vespalib/src/vespa/vespalib/util/issue.cpp b/vespalib/src/vespa/vespalib/util/issue.cpp index 9526d8d6bcd..d60423bfa4d 100644 --- a/vespalib/src/vespa/vespalib/util/issue.cpp +++ b/vespalib/src/vespa/vespalib/util/issue.cpp @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "issue.h" +#include "stringfmt.h" #include LOG_SETUP(".vespalib.issue"); @@ -13,7 +14,7 @@ using Link = Issue::Binding::Link; struct LogIssues : Issue::Handler { void handle(const Issue &issue) override { - LOG(warning, "issue not captured: %s", issue.message().c_str()); + LOG(warning, "unhandled issue: %s", issue.message().c_str()); } }; @@ -30,8 +31,8 @@ Link **get_head() { } // -Issue::Issue(const vespalib::string &message) - : _message(message) +Issue::Issue(vespalib::string message) + : _message(std::move(message)) { } @@ -62,4 +63,26 @@ Issue::listen(Handler &handler) return Binding(handler); } +void +Issue::report(vespalib::string msg) +{ + report(Issue(std::move(msg))); +} + +void +Issue::report(const std::exception &e) +{ + report(Issue(e.what())); +} + +void +Issue::report(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + vespalib::string msg = make_string_va(format, ap); + va_end(ap); + report(Issue(std::move(msg))); +} + } diff --git a/vespalib/src/vespa/vespalib/util/issue.h b/vespalib/src/vespa/vespalib/util/issue.h index 7cb4ebaff59..a98997dddf4 100644 --- a/vespalib/src/vespa/vespalib/util/issue.h +++ b/vespalib/src/vespa/vespalib/util/issue.h @@ -22,7 +22,7 @@ namespace vespalib { * explicitly wire all issues through them. * * An Issue object represents a single issue. The static 'report' - * function is used to report an issue. The static 'listen' function + * functions are used to report an issue. The static 'listen' function * is used to bind an Issue::Handler to the current thread using a * special object that should reside on the stack and unbinds the * handler when destructed. Handler bindings can be nested. Issue @@ -36,7 +36,7 @@ class Issue private: vespalib::string _message; public: - Issue(const vespalib::string &message); + Issue(vespalib::string message); const vespalib::string &message() const { return _message; } struct Handler { virtual void handle(const Issue &issue) = 0; @@ -61,6 +61,14 @@ public: }; static void report(const Issue &issue); static Binding listen(Handler &handler); + static void report(vespalib::string msg); + static void report(const std::exception &e); + static void report(const char *format, ...) +#ifdef __GNUC__ + // Add printf format checks with gcc + __attribute__ ((format (printf,1,2))) +#endif + ; }; } -- cgit v1.2.3