diff options
author | Matthew Bauer <mjbauer95@gmail.com> | 2020-07-30 14:59:57 -0500 |
---|---|---|
committer | Matthew Bauer <mjbauer95@gmail.com> | 2020-07-30 14:59:57 -0500 |
commit | d7ffe327aeab94ad1c7a27ca0c83436b92ac60fa (patch) | |
tree | 25cf09e48e5c42a320be1df2e4e9511883ad93ec /src/libutil/error.hh | |
parent | baaab2aab58aa3c47517d4ba9121a29a7ad73078 (diff) | |
parent | a785b3eddf8c02750b1715939069d20980bd5125 (diff) |
Merge remote-tracking branch 'origin/master' into fix-and-ci-static-builds
Diffstat (limited to 'src/libutil/error.hh')
-rw-r--r-- | src/libutil/error.hh | 93 |
1 files changed, 60 insertions, 33 deletions
diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 1e6102ce1..0daaf3be2 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -1,8 +1,8 @@ #pragma once - #include "ref.hh" #include "types.hh" +#include "fmt.hh" #include <cstring> #include <list> @@ -10,7 +10,9 @@ #include <map> #include <optional> -#include "fmt.hh" +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> /* 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 @@ -25,20 +27,20 @@ namespace nix { /* -This file defines two main structs/classes used in nix error handling. + This file defines two main structs/classes used in nix error handling. -ErrorInfo provides a standard payload of error information, with conversion to string -happening in the logger rather than at the call site. + ErrorInfo provides a standard payload of error information, with conversion to string + happening in the logger rather than at the call site. -BaseError is the ancestor of nix specific exceptions (and Interrupted), and contains -an ErrorInfo. + BaseError is the ancestor of nix specific exceptions (and Interrupted), and contains + an ErrorInfo. -ErrorInfo structs are sent to the logger as part of an exception, or directly with the -logError or logWarning macros. + ErrorInfo structs are sent to the logger as part of an exception, or directly with the + logError or logWarning macros. -See the error-demo.cc program for usage examples. + See the error-demo.cc program for usage examples. -*/ + */ typedef enum { lvlError = 0, @@ -50,11 +52,25 @@ typedef enum { lvlVomit } Verbosity; +typedef enum { + foFile, + foStdin, + foString +} FileOrigin; + +// the lines of code surrounding an error. +struct LinesOfCode { + std::optional<string> prevLineOfCode; + std::optional<string> errLineOfCode; + std::optional<string> nextLineOfCode; +}; + // ErrPos indicates the location of an error in a nix file. struct ErrPos { int line = 0; int column = 0; string file; + FileOrigin origin; operator bool() const { @@ -65,9 +81,14 @@ struct ErrPos { template <class P> ErrPos& operator=(const P &pos) { + origin = pos.origin; line = pos.line; column = pos.column; - file = pos.file; + // is file symbol null? + if (pos.file.set()) + file = pos.file; + else + file = ""; return *this; } @@ -78,11 +99,9 @@ struct ErrPos { } }; -struct NixCode { - ErrPos errPos; - std::optional<string> prevLineOfCode; - std::optional<string> errLineOfCode; - std::optional<string> nextLineOfCode; +struct Trace { + std::optional<ErrPos> pos; + hintformat hint; }; struct ErrorInfo { @@ -90,19 +109,19 @@ struct ErrorInfo { string name; string description; std::optional<hintformat> hint; - std::optional<NixCode> nixCode; + std::optional<ErrPos> errPos; + std::list<Trace> traces; static std::optional<string> programName; }; -std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); +std::ostream& showErrorInfo(std::ostream &out, const ErrorInfo &einfo, bool showTrace); /* 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. mutable ErrorInfo err; mutable std::optional<string> what_; @@ -113,23 +132,23 @@ public: template<typename... Args> BaseError(unsigned int status, const Args & ... args) - : err { .level = lvlError, - .hint = hintfmt(args...) - } + : err {.level = lvlError, + .hint = hintfmt(args...) + } , status(status) { } template<typename... Args> BaseError(const std::string & fs, const Args & ... args) - : err { .level = lvlError, - .hint = hintfmt(fs, args...) - } + : err {.level = lvlError, + .hint = hintfmt(fs, args...) + } { } BaseError(hintformat hint) - : err { .level = lvlError, - .hint = hint - } + : err {.level = lvlError, + .hint = hint + } { } BaseError(ErrorInfo && e) @@ -150,10 +169,17 @@ public: #endif const string & msg() const { return calcWhat(); } - const string & prefix() const { return prefix_; } - BaseError & addPrefix(const FormatOrString & fs); - const ErrorInfo & info() { calcWhat(); return err; } + + template<typename... Args> + BaseError & addTrace(std::optional<ErrPos> e, const string &fs, const Args & ... args) + { + return addTrace(e, hintfmt(fs, args...)); + } + + BaseError & addTrace(std::optional<ErrPos> e, hintformat hint); + + bool hasTrace() const { return !err.traces.empty(); } }; #define MakeError(newClass, superClass) \ @@ -165,6 +191,7 @@ public: } MakeError(Error, BaseError); +MakeError(UsageError, Error); class SysError : public Error { @@ -173,7 +200,7 @@ public: template<typename... Args> SysError(const Args & ... args) - :Error("") + : Error("") { errNo = errno; auto hf = hintfmt(args...); |