From b3e24cb3e53eabf47b5857043e13cc6473aebaa7 Mon Sep 17 00:00:00 2001 From: Qyriad Date: Tue, 18 Nov 2025 12:23:53 +0100 Subject: [PATCH] new option: abort-on-warn Co-authored-by: Emilia Bopp Change-Id: I3c3347e51d8543fbeb2b4e6ed12b0f556a6a6964 --- doc/manual/rl-next/builtins-warn.md | 4 +++- lix/libexpr/meson.build | 1 + lix/libexpr/primops.cc | 5 +++++ lix/libexpr/settings/abort-on-warn.md | 10 ++++++++++ .../lang/builtins.warn/eval-fail-abort.err.exp | 9 +++++++++ tests/functional2/lang/builtins.warn/in-abort.nix | 1 + tests/functional2/lang/builtins.warn/test.toml | 5 +++++ 7 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 lix/libexpr/settings/abort-on-warn.md create mode 100644 tests/functional2/lang/builtins.warn/eval-fail-abort.err.exp create mode 100644 tests/functional2/lang/builtins.warn/in-abort.nix diff --git a/doc/manual/rl-next/builtins-warn.md b/doc/manual/rl-next/builtins-warn.md index b474866d0..c5c6e2b9e 100644 --- a/doc/manual/rl-next/builtins-warn.md +++ b/doc/manual/rl-next/builtins-warn.md @@ -10,4 +10,6 @@ Like `builtins.trace`, it takes two arguments: the message to emit, and the expr _Unlike_ `builtins.trace`, `builtins.warn` requires the first argument — the message — to be a string. In the future we may extend `builtins.warn` to accept a more structured API. -To go along with this, we also have a new config setting [`debugger-on-warn`](@docroot@/command-ref/conf-file.md#conf-debugger-on-warn), which, when used with `--debugger`, makes `builtins.warn` also function like [`builtins.break`](@docroot@/language/builtins.md#builtins-break). +To go along with this, we also have two new config settings: +- [`debugger-on-warn`](@docroot@/command-ref/conf-file.md#conf-debugger-on-warn), which, when used with `--debugger`, makes `builtins.warn` also function like [`builtins.break`](@docroot@/language/builtins.md#builtins-break). +- [`abort-on-warn`](@docroot@/command-ref/conf-file.md#conf-abort-on-warn), which aborts evaluation entirely after the warning is emitted. diff --git a/lix/libexpr/meson.build b/lix/libexpr/meson.build index 0e56b9139..c33d35022 100644 --- a/lix/libexpr/meson.build +++ b/lix/libexpr/meson.build @@ -15,6 +15,7 @@ subdir('flake') libexpr_setting_definitions = files( # keep-sorted start + 'settings/abort-on-warn.md', 'settings/allow-import-from-derivation.md', 'settings/allow-unsafe-native-code-during-evaluation.md', 'settings/allowed-uris.md', diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index 32d65dbd7..8a472aaef 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -779,6 +779,11 @@ static void prim_warn(EvalState & state, Value ** args, Value & v) printTaggedWarning("%s", Uncolored(msg)); + if (evalSettings.abortOnWarn) { + state.ctx.errors.make("evaluation aborted (abort-on-warn)") + .debugThrow(); + } + if (evalSettings.debuggerOnWarn) { if (auto const trace = state.ctx.nextDebugTrace()) { auto const error = EvalError(ErrorInfo{ diff --git a/lix/libexpr/settings/abort-on-warn.md b/lix/libexpr/settings/abort-on-warn.md new file mode 100644 index 000000000..61d881273 --- /dev/null +++ b/lix/libexpr/settings/abort-on-warn.md @@ -0,0 +1,10 @@ +--- +name: abort-on-warn +internalName: abortOnWarn +type: bool +default: false +--- +If set to true, [`builtins.warn`](@docroot@/language/builtins.md#builtins-warn) will throw an error when logging a warning. +This will give you a stack trace that leads to the location of the warning. +This is useful for finding information about warnings in third-party Nix code when you can not start the interactive debugger, such as when Nix is called from a non-interactive script. See [`debugger-on-warn`](#conf-debugger-on-warn). +Currently, a stack trace can only be produced when the debugger is enabled, or when evaluation is aborted. diff --git a/tests/functional2/lang/builtins.warn/eval-fail-abort.err.exp b/tests/functional2/lang/builtins.warn/eval-fail-abort.err.exp new file mode 100644 index 000000000..0dbea23c8 --- /dev/null +++ b/tests/functional2/lang/builtins.warn/eval-fail-abort.err.exp @@ -0,0 +1,9 @@ +warning: meow +error: + … while calling the 'warn' builtin + at /pwd/in.nix:1:1: + 1| builtins.warn "meow" (throw "must abort before this") + | ^ + 2| + + error: evaluation aborted (abort-on-warn) diff --git a/tests/functional2/lang/builtins.warn/in-abort.nix b/tests/functional2/lang/builtins.warn/in-abort.nix new file mode 100644 index 000000000..e838bbd46 --- /dev/null +++ b/tests/functional2/lang/builtins.warn/in-abort.nix @@ -0,0 +1 @@ +builtins.warn "meow" (throw "must abort before this") diff --git a/tests/functional2/lang/builtins.warn/test.toml b/tests/functional2/lang/builtins.warn/test.toml index db3224037..06af43cfb 100644 --- a/tests/functional2/lang/builtins.warn/test.toml +++ b/tests/functional2/lang/builtins.warn/test.toml @@ -4,3 +4,8 @@ runner = "eval-okay" [[test]] runner = "eval-fail" in = "in-reject-non-string.nix" + +[[test]] +runner = "eval-fail" +flags = ["--option", "abort-on-warn", "true"] +in = "in-abort.nix"