From a3d71dab91f77a6dc5d1b9d1974c1ca98852b879 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sat, 18 Jan 2020 13:38:41 +0200 Subject: [PATCH] utils: Update error exception, utils. --- lib/mu-store.cc | 9 +++--- lib/utils/mu-error.hh | 64 ++++++++++++++++++++++++++++++++++++++----- lib/utils/mu-utils.hh | 19 +++++++++++++ 3 files changed, 80 insertions(+), 12 deletions(-) diff --git a/lib/mu-store.cc b/lib/mu-store.cc index cf214746..139f2a74 100644 --- a/lib/mu-store.cc +++ b/lib/mu-store.cc @@ -149,9 +149,8 @@ struct Store::Private { // very basic check; just ensure there's no ',' in the address. // we don't insist on full RFC5322 if (addr.find(",") != std::string::npos) - throw Mu::Error::make(Error::Code::InvalidArgument, - "e-mail address '%s' contains comma", - addr.c_str()); + throw Mu::Error(Error::Code::InvalidArgument, + "e-mail address '%s' contains comma", addr.c_str()); if (!all_addresses.empty()) all_addresses += ','; all_addresses += addr; @@ -607,8 +606,8 @@ mu_store_get_docid_for_path (const MuStore *store, const char* path, GError **er Xapian::MSet mset (enq.get_mset (0,1)); if (mset.empty()) - throw Mu::Error::make(Error::Code::NotFound, - "message @ %s not found in store", path); + throw Mu::Error(Error::Code::NotFound, + "message @ %s not found in store", path); return *mset.begin(); diff --git a/lib/utils/mu-error.hh b/lib/utils/mu-error.hh index 18692c9e..991e71dd 100644 --- a/lib/utils/mu-error.hh +++ b/lib/utils/mu-error.hh @@ -23,17 +23,24 @@ #include #include "mu-utils.hh" +#include namespace Mu { -struct Error final: public std::runtime_error { +struct Error final: public std::exception { + enum struct Code { AccessDenied, + Command, File, + Index, Internal, InvalidArgument, NotFound, + Parsing, + Query, SchemaMismatch, + Store, }; /** @@ -43,10 +50,9 @@ struct Error final: public std::runtime_error { * #param msgarg the error diecription */ Error(Code codearg, const std::string& msgarg): - std::runtime_error(msgarg), code_{codearg} + code_{codearg}, what_{msgarg} {} - /** * Build an error from an error-code and a format string * @@ -56,13 +62,53 @@ struct Error final: public std::runtime_error { * * @return an Error object */ - __attribute__((format(printf, 2, 0))) - static Error make(Code codearg, const char *frm, ...) { + __attribute__((format(printf, 3, 0))) + Error(Code codearg, const char *frm, ...): code_{codearg} { va_list args; va_start(args, frm); - auto msg = format(frm, args); + what_ = format(frm, args); va_end(args); - return Error(codearg, msg); + } + + /** + * Build an error from a GError an error-code and a format string + * + * @param code error-code + * @param gerr a GError or {}, which is consumed + * @param frm format string + * @param ... format parameters + * + * @return an Error object + */ + __attribute__((format(printf, 4, 0))) + Error(Code codearg, GError **err, const char *frm, ...): code_{codearg} { + + va_list args; + va_start(args, frm); + what_ = format(frm, args); + va_end(args); + + if (err && *err) + what_ += format (": %s", (*err)->message); + else + what_ += ": something went wrong"; + + g_clear_error(err); + } + + /** + * DTOR + * + */ + virtual ~Error() = default; + + /** + * Get the descriptiove message. + * + * @return + */ + virtual const char* what() const noexcept override { + return what_.c_str(); } /** @@ -72,8 +118,12 @@ struct Error final: public std::runtime_error { */ Code code() const { return code_; } + + private: const Code code_; + std::string what_; + }; diff --git a/lib/utils/mu-utils.hh b/lib/utils/mu-utils.hh index 77ca897d..f5b2e61e 100644 --- a/lib/utils/mu-utils.hh +++ b/lib/utils/mu-utils.hh @@ -21,6 +21,7 @@ #define __MU_UTILS_HH__ #include +#include #include #include #include @@ -136,6 +137,24 @@ std::string size_to_string (const std::string& sizestr, bool first); std::string size_to_string (int64_t size); +/** + * Convert any ostreamable<< value to a string + * + * @param t the value + * + * @return a std::string + */ +template +static inline std::string to_string (const T& val) +{ + std::stringstream sstr; + sstr << val; + + return sstr.str(); +} + + + /** * * don't repeat these catch blocks everywhere...