From 22e6490311015e076a09d5608834bd0dec1d7020 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 28 Apr 2020 21:06:08 -0600 Subject: [PATCH] Error classname as name --- src/error-demo/error-demo.cc | 16 +++++++++--- src/libstore/sqlite.cc | 2 +- src/libstore/sqlite.hh | 2 +- src/libutil/error.cc | 29 +++++++++++----------- src/libutil/error.hh | 47 +++++++++++++++++++++--------------- 5 files changed, 55 insertions(+), 41 deletions(-) diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 14027278d..98018ca0e 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -4,10 +4,12 @@ #include #include +using namespace nix; + +MakeError(DemoError, Error); + int main() { - using namespace nix; - makeDefaultLogger(); verbosity = lvlVomit; @@ -15,6 +17,12 @@ int main() // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-demo"); + try { + throw DemoError("demo error was thrown"); + } catch (Error &e) { + logger->logEI(e.info()); + } + // For completeness sake, info through vomit levels. // But this is maybe a heavy format for those. logger->logEI( @@ -79,7 +87,7 @@ int main() .prevLineOfCode = std::nullopt, .errLineOfCode = "this is the problem line of code", .nextLineOfCode = std::nullopt - }}); + }}); // Error with previous and next lines of code. logError( @@ -93,7 +101,7 @@ int main() .prevLineOfCode = std::optional("previous line of code"), .errLineOfCode = "this is the problem line of code", .nextLineOfCode = std::optional("next line of code"), - }}); + }}); return 0; diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 3407e5826..a72cd5d88 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -196,7 +196,7 @@ SQLiteTxn::~SQLiteTxn() } } -void handleSQLiteBusy(const SQLiteBusy & e) +void handleSQLiteBusy(SQLiteBusy & e) { static std::atomic lastWarned{0}; diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh index fd04c9b07..ce27033c9 100644 --- a/src/libstore/sqlite.hh +++ b/src/libstore/sqlite.hh @@ -99,7 +99,7 @@ MakeError(SQLiteBusy, SQLiteError); [[noreturn]] void throwSQLiteError(sqlite3 * db, const FormatOrString & fs); -void handleSQLiteBusy(const SQLiteBusy & e); +void handleSQLiteBusy(SQLiteBusy & e); /* Convenience function for retrying a SQLite transaction when the database is busy. */ diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 2c34325ac..8f0e0aa1a 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -4,8 +4,7 @@ #include #include "serialise.hh" -namespace nix -{ +namespace nix { const std::string nativeSystem = SYSTEM; @@ -149,20 +148,20 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) // divider. if (einfo.name != "") - out << fmt("%1%%2%" ANSI_BLUE " --- %3% %4% %5%" ANSI_NORMAL, - prefix, - levelString, - einfo.name, - dashes, - einfo.programName.value_or("")) - << std::endl; + out << fmt("%1%%2%" ANSI_BLUE " --- %3% %4% %5%" ANSI_NORMAL, + prefix, + levelString, + einfo.name, + dashes, + einfo.programName.value_or("")) + << std::endl; else - out << fmt("%1%%2%" ANSI_BLUE " -----%3% %4%" ANSI_NORMAL, - prefix, - levelString, - dashes, - einfo.programName.value_or("")) - << std::endl; + out << fmt("%1%%2%" ANSI_BLUE " -----%3% %4%" ANSI_NORMAL, + prefix, + levelString, + dashes, + einfo.programName.value_or("")) + << std::endl; // filename. if (einfo.nixCode.has_value()) { diff --git a/src/libutil/error.hh b/src/libutil/error.hh index b715c3e45..03e43241f 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -24,8 +24,7 @@ namespace nix { using std::list; using std::vector; -typedef enum -{ +typedef enum { lvlError = 0, lvlWarn, lvlInfo, @@ -35,8 +34,7 @@ typedef enum lvlVomit } Verbosity; -struct ErrPos -{ +struct ErrPos { int line; int column; string file; @@ -57,8 +55,7 @@ struct ErrPos } }; -struct NixCode -{ +struct NixCode { ErrPos errPos; std::optional prevLineOfCode; string errLineOfCode; @@ -67,8 +64,7 @@ struct NixCode // ------------------------------------------------- // ErrorInfo. -struct ErrorInfo -{ +struct ErrorInfo { Verbosity level; string name; string description; @@ -87,12 +83,20 @@ class BaseError : public std::exception protected: string prefix_; // used for location traces etc. ErrorInfo err; - string what_; - void initWhat() + std::optional what_; + const string& calcWhat() { - std::ostringstream oss; - oss << err; - what_ = oss.str(); + if (what_.has_value()) + return *what_; + else { + err.name = sname(); + + std::ostringstream oss; + oss << err; + what_ = oss.str(); + + return *what_; + } } public: unsigned int status = 1; // exit status @@ -103,31 +107,33 @@ public: .hint = hintfmt(args...) } , status(status) - { initWhat(); } + { } template BaseError(const Args & ... args) : err { .level = lvlError, .hint = hintfmt(args...) } - { initWhat(); } + { } BaseError(ErrorInfo e) : err(e) - { initWhat(); } + { } + + virtual const char* sname() const { return "BaseError"; } #ifdef EXCEPTION_NEEDS_THROW_SPEC ~BaseError() throw () { }; - const char * what() const throw () { return what_.c_str(); } + const char * what() throw () { return calcWhat().c_str(); } #else - const char * what() const noexcept { return what_.c_str(); } + const char * what() noexcept { return calcWhat().c_str(); } #endif - const string & msg() const { return what_; } + const string & msg() { return calcWhat(); } const string & prefix() const { return prefix_; } BaseError & addPrefix(const FormatOrString & fs); - const ErrorInfo & info() const { return err; } + const ErrorInfo & info() { calcWhat(); return err; } }; #define MakeError(newClass, superClass) \ @@ -135,6 +141,7 @@ public: { \ public: \ using superClass::superClass; \ + virtual const char* sname() const override { return #newClass; } \ } MakeError(Error, BaseError);