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:
parent
139cfdfb53
commit
d00edfb28d
64
doc/manual/rl-next/better-attrpath-errors.md
Normal file
64
doc/manual/rl-next/better-attrpath-errors.md
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
---
|
||||||
|
synopsis: "Trace when the `foo` part of a `foo.bar.baz` expression errors"
|
||||||
|
cls: 1505
|
||||||
|
credits: Qyriad
|
||||||
|
category: Improvements
|
||||||
|
---
|
||||||
|
|
||||||
|
Previously, if an expression like `linux_4_9.meta.description` errored in the `linux_4_9` part, it wouldn't show you that that's the part of the expression that failed to evaluate, or even that that line of code is what caused evaluation of the failing expression.
|
||||||
|
The previous error looks like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
let
|
||||||
|
inherit (pkgs.linuxKernel.kernels) linux_4_9;
|
||||||
|
in linux_4_9.meta.description
|
||||||
|
|
||||||
|
error:
|
||||||
|
… while evaluating the attribute 'linux_4_9'
|
||||||
|
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:5:
|
||||||
|
277| } // lib.optionalAttrs config.allowAliases {
|
||||||
|
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||||
|
| ^
|
||||||
|
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||||
|
|
||||||
|
… while calling the 'throw' builtin
|
||||||
|
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:17:
|
||||||
|
277| } // lib.optionalAttrs config.allowAliases {
|
||||||
|
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||||
|
| ^
|
||||||
|
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||||
|
|
||||||
|
error: linux 4.9 was removed because it will reach its end of life within 22.11
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, the error will look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
let
|
||||||
|
inherit (pkgs.linuxKernel.kernels) linux_4_9;
|
||||||
|
in linux_4_9.meta.description
|
||||||
|
error:
|
||||||
|
… while evaluating 'linux_4_9' to select 'meta.description' on it
|
||||||
|
at «string»:3:4:
|
||||||
|
2| inherit (pkgs.linuxKernel.kernels) linux_4_9;
|
||||||
|
3| in linux_4_9.meta.description
|
||||||
|
| ^
|
||||||
|
|
||||||
|
… while evaluating the attribute 'linux_4_9'
|
||||||
|
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:5:
|
||||||
|
277| } // lib.optionalAttrs config.allowAliases {
|
||||||
|
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||||
|
| ^
|
||||||
|
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||||
|
|
||||||
|
… caused by explicit throw
|
||||||
|
at /nix/store/dk2rpyb6ndvfbf19bkb2plcz5y3k8i5v-source/pkgs/top-level/linux-kernels.nix:278:17:
|
||||||
|
277| } // lib.optionalAttrs config.allowAliases {
|
||||||
|
278| linux_4_9 = throw "linux 4.9 was removed because it will reach its end of life within 22.11";
|
||||||
|
| ^
|
||||||
|
279| linux_4_14 = throw "linux 4.14 was removed because it will reach its end of life within 23.11";
|
||||||
|
|
||||||
|
error: linux 4.9 was removed because it will reach its end of life within 22.11
|
||||||
|
```
|
||||||
|
|
||||||
|
Not only does the line of code that referenced the failing binding show up in the trace, it also tells you that it was specifically the `linux_4_9` part that failed.
|
|
@ -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;
|
||||||
e->eval(state, env, vFirst);
|
|
||||||
|
try {
|
||||||
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue