Skip to content

Commit ddbc00b

Browse files
Shahar "Dawn" Orfzakaria
Shahar "Dawn" Or
andcommitted
New CLI flag --replace-eval-errors
Co-authored-by: Farid Zakaria <[email protected]>
1 parent 2704757 commit ddbc00b

File tree

7 files changed

+54
-0
lines changed

7 files changed

+54
-0
lines changed

doc/manual/source/command-ref/nix-instantiate.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ standard input.
112112
When used with `--eval`, print the resulting value as an JSON
113113
representation of the abstract syntax tree rather than as a Nix expression.
114114
115+
- `--replace-eval-errors`
116+
117+
When used with `--eval` and `--json`, replace any evaluation errors with the string
118+
`"«evaluation error»"`.
119+
115120
- `--xml`
116121
117122
When used with `--eval`, print the resulting value as an XML
@@ -205,3 +210,10 @@ $ nix-instantiate --eval --xml --strict --expr '{ x = {}; }'
205210
</attrs>
206211
</expr>
207212
```
213+
214+
Replacing evaluation errors:
215+
216+
```console
217+
$ nix-instantiate --eval --json --replace-eval-errors --expr '{ a = throw "fail"; }'
218+
{"a":"«evaluation error»"}
219+
```

src/libexpr/include/nix/expr/eval-settings.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ struct EvalSettings : Config
5353

5454
std::vector<PrimOp> extraPrimOps;
5555

56+
Setting<bool> replaceEvalErrors{
57+
this, false, "replace-eval-errors",
58+
R"(
59+
If set to `true`, the Nix evaluator will replace evaluation errors
60+
with a fixed value.
61+
)"};
62+
5663
Setting<bool> enableNativeCode{this, false, "allow-unsafe-native-code-during-evaluation", R"(
5764
Enable built-in functions that allow executing native code.
5865

src/libexpr/value-to-json.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ json printValueAsJSON(EvalState & state, bool strict,
6161
try {
6262
out.emplace(state.symbols[a->name], printValueAsJSON(state, strict, *a->value, a->pos, context, copyToStore));
6363
} catch (Error & e) {
64+
65+
bool isEvalError = dynamic_cast<EvalError *>(&e);
66+
bool isFileNotFoundError = dynamic_cast<FileNotFound *>(&e);
67+
// Restrict replaceEvalErrors only only evaluation errors
68+
if (state.settings.replaceEvalErrors && (isEvalError || isFileNotFoundError)) {
69+
out.emplace(state.symbols[a->name], "«evaluation error»");
70+
continue;
71+
}
72+
6473
e.addTrace(state.positions[a->pos],
6574
HintFmt("while evaluating attribute '%1%'", state.symbols[a->name]));
6675
throw;

src/nix-instantiate/nix-instantiate.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ static int main_nix_instantiate(int argc, char * * argv)
147147
xmlOutputSourceLocation = false;
148148
else if (*arg == "--strict")
149149
strict = true;
150+
else if (*arg == "--replace-eval-errors")
151+
evalSettings.replaceEvalErrors = true;
150152
else if (*arg == "--dry-run")
151153
settings.readOnlyMode = true;
152154
else if (*arg != "" && arg->at(0) == '-')

src/nix/eval.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ R""(
4848
# cat ./out/subdir/bla
4949
123
5050

51+
* Replace evaluation errors:
52+
53+
```console
54+
$ nix eval --json --replace-eval-errors --expr '{ a = throw "fail"; }'
55+
{"a":"«evaluation error»"}
56+
```
57+
5158
# Description
5259

5360
This command evaluates the given Nix expression, and prints the result on standard output.

tests/functional/eval.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ nix-instantiate --eval -E 'assert 1 + 2 == 3; true'
3535
[[ $(nix-instantiate -A int --eval - < "./eval.nix") == 123 ]]
3636
[[ "$(nix-instantiate --eval -E '{"assert"=1;bar=2;}')" == '{ "assert" = 1; bar = 2; }' ]]
3737

38+
expected="$(echo '{
39+
"missingAttr":"«evaluation error»"
40+
}' | tr -d '\n')"
41+
actual="$(nix-instantiate --eval --json --strict --replace-eval-errors "./replace-eval-errors.nix")" || true
42+
[[ $actual == "$expected" ]] || diff --unified <(echo "$actual") <(echo "$expected") >&2
43+
44+
actual="$(nix eval --json --replace-eval-errors -f "./replace-eval-errors.nix")"
45+
[[ $actual == "$expected" ]] || diff --unified <(echo "$actual") <(echo "$expected") >&2
46+
47+
3848
# Check that symlink cycles don't cause a hang.
3949
ln -sfn cycle.nix "$TEST_ROOT/cycle.nix"
4050
(! nix eval --file "$TEST_ROOT/cycle.nix")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
missingAttr =
3+
let
4+
bar = { };
5+
in
6+
bar.notExist;
7+
}

0 commit comments

Comments
 (0)