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
Add builtins.warn
#10592
base: master
Are you sure you want to change the base?
Add builtins.warn
#10592
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
src/libexpr/primops.cc
Outdated
if (args[0]->type() == nString) | ||
printMsg(lvlWarn, ANSI_WARNING "warning:" ANSI_NORMAL " %1%", args[0]->string_view()); | ||
else | ||
printMsg(lvlWarn, ANSI_WARNING "warning:" ANSI_NORMAL " %1%", ValuePrinter(state, *args[0])); |
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.
Why do we need to redo the error formatting here, vs reused something from the loggers?
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.
It now uses logWarning
, which also sets us up to print an actual position, after #10597.
} | ||
|
||
if (evalSettings.builtinsAbortOnWarn) { | ||
state.error<Abort>("aborting to reveal stack trace of warning, as abort-on-warn is set").debugThrow(); |
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.
Optional: we could also just throw our BaseError
with this as extra context.
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.
I prefer to treat them separately, because they don't have the same message, and I don't think it should be just a single message.
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.
Totally fine! Though just to be clear, I was thinking the this message would become an addTrace
call --- I too don't think it should be a single message.
} | ||
|
||
if (evalSettings.builtinsAbortOnWarn) { | ||
state.error<Abort>("aborting to reveal stack trace of warning, as abort-on-warn is set").debugThrow(); |
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.
Totally fine! Though just to be clear, I was thinking the this message would become an addTrace
call --- I too don't think it should be a single message.
src/libexpr/primops.cc
Outdated
if ((evalSettings.builtinsTraceDebugger || evalSettings.builtinsDebuggerOnWarn) && state.debugRepl && !state.debugTraces.empty()) { | ||
const DebugTrace & last = state.debugTraces.front(); | ||
state.runDebugRepl(nullptr, last.env, last.expr); | ||
} |
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.
A few of the call sites runDebugRepl
look similar --- not just builtin.trace
's even. Should we abstract over this a bit?
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.
I think yes, by allowing any primop to be marked as a breakpoint.
Until we have that, let's just keep it simple.
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.
Just to be clear, I mean not a new generalized feature, but something very mechanical:
if (state.debugRepl && !state.debugTraces.empty()) {
const DebugTrace & last = state.debugTraces.front();
state.runDebugRepl(<some-expression>, last.env, last.expr);
}
seems to be part of this EvalErrorBuilder<T>::debugThrow
, primop_break
, primop_trace
, and now prim_warn
. So I am wondering if a new function (maybe in header, taking an auto &&
lambda, to get the laziness right) is warranted.
msg.atPos(state.positions[pos]); | ||
auto info = msg.info(); | ||
info.level = lvlWarn; | ||
logWarning(info); |
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.
If I understand correctly, users will not be able to easily distinguish output produced by builtins.warn
from output produced by other calls of logWarning
. However, other callsites will not go ahead and trigger the "abort on warn" behaviour. It's a safe bet that you'll have some users set NIX_ABORT_ON_WARN
, then hit one of the other codepaths, and be confused why Nix did not abort.
I don't think that it's a solution to have Nix abort on all these kinds of warnings. There are rather benign warnings too, like:
warning: Git tree '...' is dirty
warning: unknown flake output 'homeModules'
The only proposal I have is to use some other logging prefix, like eval-warning:
instead of warning:
to make the distinction more clear.
Constructing ErrorInfo is a little awkward for now, but this does produce a richer log entry.
... so that we may perhaps later extend the interface. Note that Nixpkgs' lib.warn already requires a string coercible argument, so this is reasonable. Also note that string coercible values aren't all strings, but in practice, for warn, they are.
Trivial rebase for CI 🤞 |
} | ||
|
||
if (evalSettings.builtinsAbortOnWarn) { | ||
state.error<Abort>("aborting to reveal stack trace of warning, as abort-on-warn is set").debugThrow(); |
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 shouldn't throw Abort
, since that's a subclass of EvalError
, which causes the error to be stored in the eval cache. So it should be an exception type that is not a subclass of EvalError
.
Can you add a release note for this? |
Motivation
A variation of
trace
, buttrace
calls (ie intentional "info level" or trace logging).trace:
in front of itContext
I'd planned to add this a long time ago but forgot to eventually follow up on it.
This Nixpkgs PR reminded me to complete it, and I would like to avoid an unnecessary deprecation.
It proposes to rename the environment variable, which would make the current
lib.warn
not an (anachronistic) polyfill of the Nix feature anymore. That'd be unfortunate.Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.