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 af94db77cf
commit 013b7ae114
2 changed files with 22 additions and 1 deletions

View file

@ -1433,7 +1433,22 @@ 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;
e->eval(state, env, vFirst);
try {
e->eval(state, env, vFirst);
} catch (Error & e) {
assert(this->e != nullptr);
std::stringstream selectedOn;
this->e->show(state.symbols, selectedOn);
state.addErrorTrace(
e,
getPos(),
"while evaluating '%s' to select '%s' on it",
"a",
"foo"
);
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