trace when the foo part of foo.bar.baz errors

Turns errors like:

let
  errpkg = throw "invalid foobar";
in errpkg.meta

error:
       … while calling the 'throw' builtin
         at «string»:2:12:
            1| let
            2|   errpkg = throw "invalid foobar";
             |            ^
            3| in errpkg.meta

       error: invalid foobar

into errors like:

let
  errpkg = throw "invalid foobar";
in errpkg.meta

error:
       … while evaluating 'errpkg' to select 'meta' on it
         at «string»:3:4:
            2|   errpkg = throw "invalid foobar";
            3| in errpkg.meta
             |    ^

       … while calling the 'throw' builtin
         at «string»:2:12:
            1| let
            2|   errpkg = throw "invalid foobar";
             |            ^
            3| in errpkg.meta

       error: invalid foobar

For the low price of one try/catch, you too can have the incorrect line
of code actually show up in the trace!

Change-Id: If8d6200ec1567706669d405c34adcd7e2d2cd29d
This commit is contained in:
Qyriad 2024-06-22 21:22:29 -06:00
parent 99e8dd050c
commit 774dd366e9
2 changed files with 20 additions and 1 deletions

View file

@ -1432,7 +1432,20 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
Value * vCurrent = &vFirst; Value * vCurrent = &vFirst;
// Position for the current attrset Value in this select chain. // Position for the current attrset Value in this select chain.
PosIdx posCurrent; PosIdx posCurrent;
try {
e->eval(state, env, vFirst); e->eval(state, env, vFirst);
} catch (Error & e) {
assert(this->e != nullptr);
state.addErrorTrace(
e,
getPos(),
"while evaluating '%s' to select '%s' on it",
ExprPrinter(state, *this->e),
showAttrPath(state.symbols, this->attrPath)
);
throw;
}
try { try {
auto dts = state.debugRepl auto dts = state.debugRepl

View file

@ -1,4 +1,10 @@
error: error:
… while evaluating 'a' to select 'foo' on it
at /pwd/lang/eval-fail-recursion.nix:1:21:
1| let a = {} // a; in a.foo
| ^
2|
… in the right operand of the update (//) operator … in the right operand of the update (//) operator
at /pwd/lang/eval-fail-recursion.nix:1:12: at /pwd/lang/eval-fail-recursion.nix:1:12:
1| let a = {} // a; in a.foo 1| let a = {} // a; in a.foo