diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index f7ab56271..8551eb048 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -281,6 +281,8 @@ int handleExceptions(const string & programName, std::function fun) { ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this + ErrorInfo::programName = programName; + string error = ANSI_RED "error:" ANSI_NORMAL " "; try { try { @@ -296,12 +298,15 @@ int handleExceptions(const string & programName, std::function fun) } catch (Exit & e) { return e.status; } catch (UsageError & e) { + // TODO: switch to logError + // logError(e.info()); printError( - format(error + "%1%\nTry '%2% --help' for more information.") + format("%1%\nTry '%2% --help' for more information.") % e.what() % programName); return 1; } catch (BaseError & e) { - printError(error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); + // logError(e.info()); + printError("%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); if (e.prefix() != "" && !settings.showTrace) printError("(use '--show-trace' to show detailed location information)"); return e.status; diff --git a/src/libutil/error.cc b/src/libutil/error.cc index c6bca7135..20b97ea3d 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -7,6 +7,24 @@ namespace nix { + +const std::string nativeSystem = SYSTEM; + + +BaseError & BaseError::addPrefix(const FormatOrString & fs) +{ + prefix_ = fs.s + prefix_; + return *this; +} + + +std::string SysError::addErrno(const std::string & s) +{ + errNo = errno; + return s + ": " + strerror(errNo); +} + + std::optional ErrorInfo::programName = std::nullopt; std::ostream& operator<<(std::ostream &os, const hintformat &hf) diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 141bc6b3c..f11256f61 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -5,20 +5,8 @@ #include #include -#include #include -#include -#include "fmt.hh" - -/* Before 4.7, gcc's std::exception uses empty throw() specifiers for - * its (virtual) destructor and what() in c++11 mode, in violation of spec - */ -#ifdef __GNUC__ -#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) -#define EXCEPTION_NEEDS_THROW_SPEC -#endif -#endif namespace nix { @@ -26,144 +14,13 @@ using std::list; using std::set; using std::vector; -typedef enum { - lvlError = 0, - lvlWarn, - lvlInfo, - lvlTalkative, - lvlChatty, - lvlDebug, - lvlVomit -} Verbosity; - -struct ErrPos -{ - int line; - int column; - string file; - - template - ErrPos& operator=(const P &pos) - { - line = pos.line; - column = pos.column; - file = pos.file; - return *this; - } - - template - ErrPos(const P &p) - { - *this = p; - } -}; - -struct NixCode -{ - ErrPos errPos; - std::optional prevLineOfCode; - string errLineOfCode; - std::optional nextLineOfCode; -}; - -// ------------------------------------------------- -// ErrorInfo. -struct ErrorInfo -{ - Verbosity level; - string name; - string description; - std::optional hint; - std::optional nixCode; - - static std::optional programName; -}; - -std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); - -/* BaseError should generally not be caught, as it has Interrupted as - a subclass. Catch Error instead. */ -class BaseError : public std::exception -{ -protected: - string prefix_; // used for location traces etc. - ErrorInfo err; - string what_; - void initWhat() - { - std::ostringstream oss; - oss << err; - what_ = oss.str(); - } -public: - unsigned int status = 1; // exit status - - template - BaseError(unsigned int status, const Args & ... args) - : err { .level = lvlError, - .hint = hintfmt(args...) - } - , status(status) - { initWhat(); } - - template - BaseError(const Args & ... args) - : err { .level = lvlError, - .hint = hintfmt(args...) - } - { initWhat(); } - - BaseError(ErrorInfo e) - : err(e) - { initWhat(); } - -#ifdef EXCEPTION_NEEDS_THROW_SPEC - ~BaseError() throw () { }; - const char * what() const throw () { return what_.c_str(); } -#else - const char * what() const noexcept { return what_.c_str(); } -#endif - - const string & msg() const { return what_; } - const string & prefix() const { return prefix_; } - BaseError & addPrefix(const FormatOrString & fs); - - const ErrorInfo & info() const { return err; } -}; - -#define MakeError(newClass, superClass) \ - class newClass : public superClass \ - { \ - public: \ - using superClass::superClass; \ - } - -MakeError(Error, BaseError); - -class SysError : public Error -{ -public: - int errNo; - - template - SysError(const Args & ... args) - : Error(args...) // TODO addErrNo for hintfmt - // : Error(addErrno(hintfmt(args...))) - { } - -private: - - std::string addErrno(const std::string & s); -}; - - -typedef list Strings; -typedef set StringSet; +typedef list Strings; +typedef set StringSet; typedef std::map StringMap; - /* Paths are just strings. */ -typedef string Path; + +typedef std::string Path; typedef list Paths; typedef set PathSet; diff --git a/src/libutil/util.cc b/src/libutil/util.cc index bffcbcccf..747a9e991 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -40,24 +40,6 @@ extern char * * environ; namespace nix { - -const std::string nativeSystem = SYSTEM; - - -BaseError & BaseError::addPrefix(const FormatOrString & fs) -{ - prefix_ = fs.s + prefix_; - return *this; -} - - -std::string SysError::addErrno(const std::string & s) -{ - errNo = errno; - return s + ": " + strerror(errNo); -} - - std::optional getEnv(const std::string & key) { char * value = getenv(key.c_str()); diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 636f3ba6c..978e14a30 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -1,6 +1,7 @@ #pragma once #include "types.hh" +#include "error.hh" #include "logging.hh" #include "ansicolor.hh"