query
On this page

warn

lib.trivial.warn

Primop
Docs pulled from | This Revision | about 1 hour ago


Nixpkgs manual

warn message value

Print a warning before returning the second argument.

See builtins.warn (Nix >= 2.23). On older versions, the Nix 2.23 behavior is emulated with builtins.trace, including the NIX_ABORT_ON_WARN behavior, but not the nix.conf setting or command line option.

Inputs

message (String)

Warning message to print before evaluating value.

value (any value)

Value to return as-is.

Type

warn :: String -> a -> a

Nix manual

Takes 2 arguments

e1, e2

Evaluate e1, which must be a string, and print it on standard error as a warning. Then return e2. This function is useful for non-critical situations where attention is advisable.

If the debugger-on-trace or debugger-on-warn option is set to true and the --debugger flag is given, the interactive debugger will be started when warn is called (like break).

If the abort-on-warn option is set, the evaluation is aborted after the warning is printed. This is useful to reveal the stack trace of the warning, when the context is non-interactive and a debugger can not be launched.

Noogle detected

Aliases

Implementation

This function is implemented in c++ and is part of the native nix runtime.

src/libexpr/primops.cc:1339

static void prim_warn(EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
    // We only accept a string argument for now. The use case for pretty printing a value is covered by `trace`.
    // By rejecting non-strings we allow future versions to add more features without breaking existing code.
    auto msgStr =
        state.forceString(*args[0], pos, "while evaluating the first argument; the message passed to builtins.warn");

    {
        ErrorInfo info{
            .level = lvlWarn,
            .msg = HintFmt(std::string(msgStr)),
            .pos = state.positions[pos],
            .isFromExpr = true,
        };
        logWarning(info);
    }

    if (state.settings.builtinsAbortOnWarn) {
        // Not an EvalError or subclass, which would cause the error to be stored in the eval cache.
        state.error<EvalBaseError>("aborting to reveal stack trace of warning, as abort-on-warn is set")
            .setIsFromExpr()
            .debugThrow();
    }
    if (state.settings.builtinsTraceDebugger || state.settings.builtinsDebuggerOnWarn) {
        state.runDebugRepl(nullptr);
    }
    state.forceValue(*args[1], pos);
    v = *args[1];
}

Implementation

The following is the current implementation of this function.

warn =
    # Since Nix 2.23, https://github.com/NixOS/nix/pull/10592
    builtins.warn or (
      let
        mustAbort = lib.elem (builtins.getEnv "NIX_ABORT_ON_WARN") [
          "1"
          "true"
          "yes"
        ];
      in
      # Do not eta reduce v, so that we have the same strictness as `builtins.warn`.
      msg: v:
      # `builtins.warn` requires a string message, so we enforce that in our implementation, so that callers aren't accidentally incompatible with newer Nix versions.
      assert isString msg;
      if mustAbort then
        builtins.trace "evaluation warning: ${msg}" (
          abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors."
        )
      else
        builtins.trace "evaluation warning: ${msg}" v
    );