1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 21:01:16 +02:00

Add a flag to start the REPL on evaluation errors

This allows interactively inspecting the state of the evaluator at the
point of failure.

Example:

  $ nix eval path:///home/eelco/Dev/nix/flake2#modules.hello-closure._final --start-repl-on-eval-errors
  error: --- TypeError -------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
  at: (20:53) in file: /nix/store/4264z41dxfdiqr95svmpnxxxwhfplhy0-source/flake.nix

      19|
      20|           _final = builtins.foldl' (xs: mod: xs // (mod._module.config { config = _final; })) _defaults _allModules;
        |                                                     ^
      21|         };

  attempt to call something which is not a function but a set

  Starting REPL to allow you to inspect the current state of the evaluator.

  The following extra variables are in scope: arg, fun

  Welcome to Nix version 2.4. Type :? for help.

  nix-repl> fun
  error: --- EvalError -------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
  at: (150:28) in file: /nix/store/4264z41dxfdiqr95svmpnxxxwhfplhy0-source/flake.nix

     149|
     150|           tarballClosure = (module {
        |                            ^
     151|             extends = [ self.modules.derivation ];

  attribute 'derivation' missing

  nix-repl> :t fun
  a set

  nix-repl> builtins.attrNames fun
  [ "tarballClosure" ]

  nix-repl>
This commit is contained in:
Eelco Dolstra 2020-08-05 21:26:17 +02:00
parent b3e73547a0
commit e5662ba652
5 changed files with 91 additions and 32 deletions

View file

@ -1171,6 +1171,8 @@ void EvalState::callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos)
}
}
std::function<void(const Error & error, const std::map<std::string, Value *> & env)> debuggerHook;
void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos)
{
auto trace = evalSettings.traceFunctionCalls ? std::make_unique<FunctionCallTrace>(pos) : nullptr;
@ -1198,8 +1200,15 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
}
}
if (fun.type != tLambda)
throwTypeError(pos, "attempt to call something which is not a function but %1%", fun);
if (fun.type != tLambda) {
auto error = TypeError({
.hint = hintfmt("attempt to call something which is not a function but %1%", showType(fun)),
.errPos = pos
});
if (debuggerHook)
debuggerHook(error, {{"fun", &fun}, {"arg", &arg}});
throw error;
}
ExprLambda & lambda(*fun.lambda.fun);