mirror of
https://github.com/NixOS/nix
synced 2025-07-06 13:21:47 +02:00
Merge pull request #9834 from 9999years/structured-errors
Towards structured error classes
This commit is contained in:
commit
1ba9780cf5
42 changed files with 790 additions and 660 deletions
|
@ -335,7 +335,7 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s
|
|||
* try {
|
||||
* e->eval(*this, env, v);
|
||||
* if (v.type() != nAttrs)
|
||||
* throwTypeError("expected a set but found %1%", v);
|
||||
* error<TypeError>("expected a set but found %1%", v);
|
||||
* } catch (Error & e) {
|
||||
* e.addTrace(pos, errorCtx);
|
||||
* throw;
|
||||
|
@ -349,7 +349,7 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s
|
|||
* e->eval(*this, env, v);
|
||||
* try {
|
||||
* if (v.type() != nAttrs)
|
||||
* throwTypeError("expected a set but found %1%", v);
|
||||
* error<TypeError>("expected a set but found %1%", v);
|
||||
* } catch (Error & e) {
|
||||
* e.addTrace(pos, errorCtx);
|
||||
* throw;
|
||||
|
@ -411,7 +411,7 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s
|
|||
|
||||
oss << einfo.msg << "\n";
|
||||
|
||||
printPosMaybe(oss, "", einfo.errPos);
|
||||
printPosMaybe(oss, "", einfo.pos);
|
||||
|
||||
auto suggestions = einfo.suggestions.trim();
|
||||
if (!suggestions.suggestions.empty()) {
|
||||
|
|
|
@ -31,15 +31,6 @@
|
|||
#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
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
|
||||
#define EXCEPTION_NEEDS_THROW_SPEC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
|
@ -84,9 +75,14 @@ inline bool operator>=(const Trace& lhs, const Trace& rhs);
|
|||
struct ErrorInfo {
|
||||
Verbosity level;
|
||||
hintformat msg;
|
||||
std::shared_ptr<Pos> errPos;
|
||||
std::shared_ptr<Pos> pos;
|
||||
std::list<Trace> traces;
|
||||
|
||||
/**
|
||||
* Exit status.
|
||||
*/
|
||||
unsigned int status = 1;
|
||||
|
||||
Suggestions suggestions;
|
||||
|
||||
static std::optional<std::string> programName;
|
||||
|
@ -103,18 +99,21 @@ class BaseError : public std::exception
|
|||
protected:
|
||||
mutable ErrorInfo err;
|
||||
|
||||
/**
|
||||
* Cached formatted contents of `err.msg`.
|
||||
*/
|
||||
mutable std::optional<std::string> what_;
|
||||
/**
|
||||
* Format `err.msg` and set `what_` to the resulting value.
|
||||
*/
|
||||
const std::string & calcWhat() const;
|
||||
|
||||
public:
|
||||
unsigned int status = 1; // exit status
|
||||
|
||||
BaseError(const BaseError &) = default;
|
||||
|
||||
template<typename... Args>
|
||||
BaseError(unsigned int status, const Args & ... args)
|
||||
: err { .level = lvlError, .msg = hintfmt(args...) }
|
||||
, status(status)
|
||||
: err { .level = lvlError, .msg = hintfmt(args...), .status = status }
|
||||
{ }
|
||||
|
||||
template<typename... Args>
|
||||
|
@ -139,16 +138,19 @@ public:
|
|||
: err(e)
|
||||
{ }
|
||||
|
||||
#ifdef EXCEPTION_NEEDS_THROW_SPEC
|
||||
~BaseError() throw () { };
|
||||
const char * what() const throw () { return calcWhat().c_str(); }
|
||||
#else
|
||||
const char * what() const noexcept override { return calcWhat().c_str(); }
|
||||
#endif
|
||||
|
||||
const std::string & msg() const { return calcWhat(); }
|
||||
const ErrorInfo & info() const { calcWhat(); return err; }
|
||||
|
||||
void withExitStatus(unsigned int status)
|
||||
{
|
||||
err.status = status;
|
||||
}
|
||||
|
||||
void atPos(std::shared_ptr<Pos> pos) {
|
||||
err.pos = pos;
|
||||
}
|
||||
|
||||
void pushTrace(Trace trace)
|
||||
{
|
||||
err.traces.push_front(trace);
|
||||
|
|
|
@ -199,7 +199,7 @@ struct JSONLogger : Logger {
|
|||
json["level"] = ei.level;
|
||||
json["msg"] = oss.str();
|
||||
json["raw_msg"] = ei.msg.str();
|
||||
to_json(json, ei.errPos);
|
||||
to_json(json, ei.pos);
|
||||
|
||||
if (loggerSettings.showTrace.get() && !ei.traces.empty()) {
|
||||
nlohmann::json traces = nlohmann::json::array();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue