-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Print the value in value is X while a Y is expected
error
#9753
Conversation
value is X while a Y is expected
error
04bb0d0
to
004bfaf
Compare
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 is a very nice change!
I played a bit around with this and it seems to be working fine. I even through this against some more complex evaluations involving flake-parts with custom modules and that seems to be producing helpful results.
From what I can tell, this looks OK code-wise from what I can tell - haven't been doing contributing much to the Nix codebase recently.
One issue I noticed however is that the opening bracket of a list/attr-set is magenta, the closing bracket isn't, i.e.
"[...] while a set was expected: " ANSI_MAGENTA "[" ANSI_CYAN " 2 3 " ANSI_NORMAL "]"
E.g. reproducible with ./result/bin/nix-instantiate --eval -E '[ 1 2 ] // {}'
.
Also, I'm wondering if it'd make sense to do a little bit of pretty-printing for lists and attr-sets, though that'd require changes on existing code, so that's a follow-up I guess.
664d1b1
to
1c1225a
Compare
src/libexpr/eval.cc
Outdated
#include <fstream> | ||
#include <functional> | ||
#include <strstream> |
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.
Btw any particular reason for using strstream here? That is deprecated for quite a while and I just realized that it doesn't build with clang (used gcc last time).
Also, reversing this change seems fine as well.
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.
Nope, fixed this to use iostream
instead.
Needed to fix the build with clang. See also NixOS#9753 (comment)
Low-hanging fruit in the spirit of NixOS#9753 and NixOS#9754 (means 9999years did all the hard work already). This basically prints out what was attempted to be called as function, i.e. map (import <nixpkgs> {}) [ 1 2 3 ] now gives the following error message: error: … while calling the 'map' builtin at «string»:1:1: 1| map (import <nixpkgs> {}) [ 1 2 3 ] | ^ … while evaluating the first argument passed to builtins.map error: expected a function but found a set: { _type = "pkgs"; AAAAAASomeThingsFailToEvaluate = «thunk»; AMB-plugins = «thunk»; ArchiSteamFarm = «thunk»; BeatSaberModManager = «thunk»; CHOWTapeModel = «thunk»; ChowCentaur = «thunk»; ChowKick = «thunk»; ChowPhaser = «thunk»; CoinMP = «thunk»; «18783 attributes elided»}
1c1225a
to
56be92f
Compare
Adds the failing value to `value is <TYPE> while a <TYPE> is expected` error messages.
56be92f
to
cb7fbd4
Compare
This is caused by the formatting logic behind As for the magenta token, you could wrap all expressions in |
That's a good idea. Can I leave it to a follow-up PR to keep this focused? |
👍 |
Low-hanging fruit in the spirit of NixOS#9753 and NixOS#9754 (means 9999years did all the hard work already). This basically prints out what was attempted to be called as function, i.e. map (import <nixpkgs> {}) [ 1 2 3 ] now gives the following error message: error: … while calling the 'map' builtin at «string»:1:1: 1| map (import <nixpkgs> {}) [ 1 2 3 ] | ^ … while evaluating the first argument passed to builtins.map error: expected a function but found a set: { _type = "pkgs"; AAAAAASomeThingsFailToEvaluate = «thunk»; AMB-plugins = «thunk»; ArchiSteamFarm = «thunk»; BeatSaberModManager = «thunk»; CHOWTapeModel = «thunk»; ChowCentaur = «thunk»; ChowKick = «thunk»; ChowPhaser = «thunk»; CoinMP = «thunk»; «18783 attributes elided»}
While preparing PRs like NixOS#9753, I've had to change error messages in dozens of code paths. It would be nice if instead of EvalError("expected 'boolean' but found '%1%'", showType(v)) we could write TypeError(v, "boolean") or similar. Then, changing the error message could be a mechanical refactor with the compiler pointing out places the constructor needs to be changed, rather than the error-prone process of grepping through the codebase. Structured errors would also help prevent the "same" error from having multiple slightly different messages, and could be a first step towards error codes / an error index. This PR reworks the exception infrastructure in `libexpr` to support exception types with different constructor signatures than `BaseError`. Actually refactoring the exceptions to use structured data will come in a future PR (this one is big enough already, as it has to touch every exception in `libexpr`). The core design is in `eval-error.hh`. Generally, errors like this: state.error("'%s' is not a string", getAttrPathStr()) .debugThrow<TypeError>() are transformed like this: EvalErrorBuilder<TypeError>(state, "'%s' is not a string", getAttrPathStr()) .debugThrow()
While preparing PRs like NixOS#9753, I've had to change error messages in dozens of code paths. It would be nice if instead of EvalError("expected 'boolean' but found '%1%'", showType(v)) we could write TypeError(v, "boolean") or similar. Then, changing the error message could be a mechanical refactor with the compiler pointing out places the constructor needs to be changed, rather than the error-prone process of grepping through the codebase. Structured errors would also help prevent the "same" error from having multiple slightly different messages, and could be a first step towards error codes / an error index. This PR reworks the exception infrastructure in `libexpr` to support exception types with different constructor signatures than `BaseError`. Actually refactoring the exceptions to use structured data will come in a future PR (this one is big enough already, as it has to touch every exception in `libexpr`). The core design is in `eval-error.hh`. Generally, errors like this: state.error("'%s' is not a string", getAttrPathStr()) .debugThrow<TypeError>() are transformed like this: EvalErrorBuilder<TypeError>(state, "'%s' is not a string", getAttrPathStr()) .debugThrow()
While preparing PRs like NixOS#9753, I've had to change error messages in dozens of code paths. It would be nice if instead of EvalError("expected 'boolean' but found '%1%'", showType(v)) we could write TypeError(v, "boolean") or similar. Then, changing the error message could be a mechanical refactor with the compiler pointing out places the constructor needs to be changed, rather than the error-prone process of grepping through the codebase. Structured errors would also help prevent the "same" error from having multiple slightly different messages, and could be a first step towards error codes / an error index. This PR reworks the exception infrastructure in `libexpr` to support exception types with different constructor signatures than `BaseError`. Actually refactoring the exceptions to use structured data will come in a future PR (this one is big enough already, as it has to touch every exception in `libexpr`). The core design is in `eval-error.hh`. Generally, errors like this: state.error("'%s' is not a string", getAttrPathStr()) .debugThrow<TypeError>() are transformed like this: EvalErrorBuilder<TypeError>(state, "'%s' is not a string", getAttrPathStr()) .debugThrow()
While preparing PRs like NixOS#9753, I've had to change error messages in dozens of code paths. It would be nice if instead of EvalError("expected 'boolean' but found '%1%'", showType(v)) we could write TypeError(v, "boolean") or similar. Then, changing the error message could be a mechanical refactor with the compiler pointing out places the constructor needs to be changed, rather than the error-prone process of grepping through the codebase. Structured errors would also help prevent the "same" error from having multiple slightly different messages, and could be a first step towards error codes / an error index. This PR reworks the exception infrastructure in `libexpr` to support exception types with different constructor signatures than `BaseError`. Actually refactoring the exceptions to use structured data will come in a future PR (this one is big enough already, as it has to touch every exception in `libexpr`). The core design is in `eval-error.hh`. Generally, errors like this: state.error("'%s' is not a string", getAttrPathStr()) .debugThrow<TypeError>() are transformed like this: EvalErrorBuilder<TypeError>(state, "'%s' is not a string", getAttrPathStr()) .debugThrow()
While preparing PRs like NixOS#9753, I've had to change error messages in dozens of code paths. It would be nice if instead of EvalError("expected 'boolean' but found '%1%'", showType(v)) we could write TypeError(v, "boolean") or similar. Then, changing the error message could be a mechanical refactor with the compiler pointing out places the constructor needs to be changed, rather than the error-prone process of grepping through the codebase. Structured errors would also help prevent the "same" error from having multiple slightly different messages, and could be a first step towards error codes / an error index. This PR reworks the exception infrastructure in `libexpr` to support exception types with different constructor signatures than `BaseError`. Actually refactoring the exceptions to use structured data will come in a future PR (this one is big enough already, as it has to touch every exception in `libexpr`). The core design is in `eval-error.hh`. Generally, errors like this: state.error("'%s' is not a string", getAttrPathStr()) .debugThrow<TypeError>() are transformed like this: state.error<TypeError>("'%s' is not a string", getAttrPathStr()) .debugThrow() The type annotation has moved from `ErrorBuilder::debugThrow` to `EvalState::error`.
While preparing PRs like NixOS#9753, I've had to change error messages in dozens of code paths. It would be nice if instead of EvalError("expected 'boolean' but found '%1%'", showType(v)) we could write TypeError(v, "boolean") or similar. Then, changing the error message could be a mechanical refactor with the compiler pointing out places the constructor needs to be changed, rather than the error-prone process of grepping through the codebase. Structured errors would also help prevent the "same" error from having multiple slightly different messages, and could be a first step towards error codes / an error index. This PR reworks the exception infrastructure in `libexpr` to support exception types with different constructor signatures than `BaseError`. Actually refactoring the exceptions to use structured data will come in a future PR (this one is big enough already, as it has to touch every exception in `libexpr`). The core design is in `eval-error.hh`. Generally, errors like this: state.error("'%s' is not a string", getAttrPathStr()) .debugThrow<TypeError>() are transformed like this: state.error<TypeError>("'%s' is not a string", getAttrPathStr()) .debugThrow() The type annotation has moved from `ErrorBuilder::debugThrow` to `EvalState::error`.
While preparing PRs like NixOS#9753, I've had to change error messages in dozens of code paths. It would be nice if instead of EvalError("expected 'boolean' but found '%1%'", showType(v)) we could write TypeError(v, "boolean") or similar. Then, changing the error message could be a mechanical refactor with the compiler pointing out places the constructor needs to be changed, rather than the error-prone process of grepping through the codebase. Structured errors would also help prevent the "same" error from having multiple slightly different messages, and could be a first step towards error codes / an error index. This PR reworks the exception infrastructure in `libexpr` to support exception types with different constructor signatures than `BaseError`. Actually refactoring the exceptions to use structured data will come in a future PR (this one is big enough already, as it has to touch every exception in `libexpr`). The core design is in `eval-error.hh`. Generally, errors like this: state.error("'%s' is not a string", getAttrPathStr()) .debugThrow<TypeError>() are transformed like this: state.error<TypeError>("'%s' is not a string", getAttrPathStr()) .debugThrow() The type annotation has moved from `ErrorBuilder::debugThrow` to `EvalState::error`.
This fixes the opening bracket of lists/attrsets being printed in magenta, unlike the closing bracket. NixOS#9753 (comment)
This fixes the opening bracket of lists/attrsets being printed in magenta, unlike the closing bracket. NixOS#9753 (comment)
Print the value in `value is X while a Y is expected` error (cherry picked from commit 5f72a97) Change-Id: Idb4bc903ae59a0f5b6fb3b1da4d47970fe0a6efe
While preparing PRs like NixOS#9753, I've had to change error messages in dozens of code paths. It would be nice if instead of EvalError("expected 'boolean' but found '%1%'", showType(v)) we could write TypeError(v, "boolean") or similar. Then, changing the error message could be a mechanical refactor with the compiler pointing out places the constructor needs to be changed, rather than the error-prone process of grepping through the codebase. Structured errors would also help prevent the "same" error from having multiple slightly different messages, and could be a first step towards error codes / an error index. This PR reworks the exception infrastructure in `libexpr` to support exception types with different constructor signatures than `BaseError`. Actually refactoring the exceptions to use structured data will come in a future PR (this one is big enough already, as it has to touch every exception in `libexpr`). The core design is in `eval-error.hh`. Generally, errors like this: state.error("'%s' is not a string", getAttrPathStr()) .debugThrow<TypeError>() are transformed like this: state.error<TypeError>("'%s' is not a string", getAttrPathStr()) .debugThrow() The type annotation has moved from `ErrorBuilder::debugThrow` to `EvalState::error`. (cherry picked from commit c6a89c1) Change-Id: Iced91ba4e00ca9e801518071fb43798936cbd05a
Motivation
Adds the failing value to
value is <TYPE> while a <TYPE> is expected
error messages.Context
Take two of #9554 now that #9606 is merged.
Partial fix for #561, in particular #561 (comment).
Priorities
Add 👍 to pull requests you find important.