-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New CLI flag --replace-eval-errors
#13095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,6 +112,11 @@ standard input. | |
When used with `--eval`, print the resulting value as an JSON | ||
representation of the abstract syntax tree rather than as a Nix expression. | ||
|
||
- `--replace-eval-errors` | ||
|
||
When used with `--eval` and `--json`, replace any evaluation errors with the string | ||
`"«evaluation error»"`. | ||
|
||
- `--xml` | ||
|
||
When used with `--eval`, print the resulting value as an XML | ||
|
@@ -205,3 +210,10 @@ $ nix-instantiate --eval --xml --strict --expr '{ x = {}; }' | |
</attrs> | ||
</expr> | ||
``` | ||
|
||
Replacing evaluation errors: | ||
|
||
```console | ||
$ nix-instantiate --eval --json --replace-eval-errors --expr '{ a = throw "fail"; }' | ||
{"a":"«evaluation error»"} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that this representation of eval errors is ambiguous, since
produces the same output. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While this is true, we already have such ambiguity, for instance:
That said, something like Considering that this originated from a |
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,12 +6,13 @@ | |
#include <cstdlib> | ||
#include <iomanip> | ||
#include <nlohmann/json.hpp> | ||
#include <typeinfo> | ||
|
||
|
||
namespace nix { | ||
using json = nlohmann::json; | ||
// TODO: rename. It doesn't print. | ||
json printValueAsJSON(EvalState & state, bool strict, | ||
json printValueAsJSON(EvalState & state, bool strict, bool replaceEvalErrors, | ||
Value & v, const PosIdx pos, NixStringContext & context, bool copyToStore) | ||
{ | ||
checkInterrupt(); | ||
|
@@ -54,13 +55,27 @@ json printValueAsJSON(EvalState & state, bool strict, | |
break; | ||
} | ||
if (auto i = v.attrs()->get(state.sOutPath)) | ||
return printValueAsJSON(state, strict, *i->value, i->pos, context, copyToStore); | ||
return printValueAsJSON(state, strict, replaceEvalErrors, *i->value, i->pos, context, copyToStore); | ||
else { | ||
out = json::object(); | ||
for (auto & a : v.attrs()->lexicographicOrder(state.symbols)) { | ||
try { | ||
out.emplace(state.symbols[a->name], printValueAsJSON(state, strict, *a->value, a->pos, context, copyToStore)); | ||
out.emplace(state.symbols[a->name], printValueAsJSON(state, strict, replaceEvalErrors, *a->value, a->pos, context, copyToStore)); | ||
} catch (Error & e) { | ||
std::cerr << "Caught an Error of type: " << typeid(e).name() << std::endl; | ||
// std::cerr << "Caught an Error of type: " << e.message() << std::endl; | ||
// std::cerr << "Caught an Error of type: " << e.what() << std::endl; | ||
|
||
// TODO: Figure out what Error is here? | ||
// We seem to be not catching FileNotFoundError. | ||
bool isEvalError = dynamic_cast<EvalError *>(&e); | ||
bool isFileNotFoundError = dynamic_cast<FileNotFound *>(&e); | ||
// Restrict replaceEvalErrors only only evaluation errors | ||
if (replaceEvalErrors && (isEvalError || isFileNotFoundError)) { | ||
out.emplace(state.symbols[a->name], "«evaluation error»"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This changes the semantics of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This ties in with the comment about making it a flag instead of a setting. |
||
continue; | ||
} | ||
|
||
e.addTrace(state.positions[a->pos], | ||
HintFmt("while evaluating attribute '%1%'", state.symbols[a->name])); | ||
throw; | ||
|
@@ -75,8 +90,9 @@ json printValueAsJSON(EvalState & state, bool strict, | |
int i = 0; | ||
for (auto elem : v.listItems()) { | ||
try { | ||
out.push_back(printValueAsJSON(state, strict, *elem, pos, context, copyToStore)); | ||
out.push_back(printValueAsJSON(state, strict, replaceEvalErrors, *elem, pos, context, copyToStore)); | ||
} catch (Error & e) { | ||
// TODO: Missing catch | ||
e.addTrace(state.positions[pos], | ||
HintFmt("while evaluating list element at index %1%", i)); | ||
throw; | ||
|
@@ -106,11 +122,11 @@ json printValueAsJSON(EvalState & state, bool strict, | |
return out; | ||
} | ||
|
||
void printValueAsJSON(EvalState & state, bool strict, | ||
void printValueAsJSON(EvalState & state, bool strict, bool replaceEvalErrors, | ||
Value & v, const PosIdx pos, std::ostream & str, NixStringContext & context, bool copyToStore) | ||
{ | ||
try { | ||
str << printValueAsJSON(state, strict, v, pos, context, copyToStore); | ||
str << printValueAsJSON(state, strict, replaceEvalErrors, v, pos, context, copyToStore); | ||
} catch (nlohmann::json::exception & e) { | ||
throw JSONSerializationError("JSON serialization error: %s", e.what()); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,13 @@ R""( | |
# cat ./out/subdir/bla | ||
123 | ||
|
||
* Replace evaluation errors: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Replace evaluation errors" is very vague (though the example does make it clear). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is clear when you have in mind the model of evaluation as term rewriting, although that's not how we introduce evaluation at all. In fact, we don't have a description of evaluation in the manual. Reminded me of although that doesn't go all that much into term rewriting either. |
||
|
||
```console | ||
$ nix eval --json --replace-eval-errors --expr '{ a = throw "fail"; }' | ||
{"a":"«evaluation error»"} | ||
``` | ||
|
||
# Description | ||
|
||
This command evaluates the given Nix expression, and prints the result on standard output. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
missingAttr = let bar = { }; in bar.notExist; | ||
insideAList = [ (throw "a throw") ]; | ||
deeper = { v = throw "v"; }; | ||
failedAssertion = assert true; assert false; null; | ||
missingFile = builtins.readFile ./missing-file.txt; | ||
missingImport = import ./missing-import.nix; | ||
outOfBounds = builtins.elemAt [ 1 2 3 ] 100; | ||
failedCoersion = "${1}"; | ||
failedAddition = 1.0 + "a string"; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't really what it does. It should say something like: any attribute that throws an evaluation error is represented by a JSON property with the string value
«evaluation error»
.