1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-29 14:53:16 +02:00

Decode virtual paths in user-thrown errors

E.g. instead of

  error: Package ‘steam’ in /__virtual__/4/pkgs/games/steam/steam.nix:43 has an unfree license (‘unfreeRedistributable’), refusing to evaluate.

you now get

  error: Package ‘steam’ in «github:nixos/nixpkgs/b82ccafb54163ab9024e893e578d840577785fea»/pkgs/games/steam/steam.nix:43 has an unfree license (‘unfreeRedistributable’), refusing to evaluate.
This commit is contained in:
Eelco Dolstra 2022-09-12 12:52:07 +02:00
parent b293b33322
commit 48a5879b63
4 changed files with 39 additions and 4 deletions

View file

@ -1757,7 +1757,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
Nix attempted to evaluate a function as a top level expression; in Nix attempted to evaluate a function as a top level expression; in
this case it must have its arguments supplied either by default this case it must have its arguments supplied either by default
values, or passed explicitly with '--arg' or '--argstr'. See values, or passed explicitly with '--arg' or '--argstr'. See
https://nixos.org/manual/nix/stable/expressions/language-constructs.html#functions.)", symbols[i.name], https://nixos.org/manual/nix/stable/expressions/language-constructs.html#functions.)", symbols[i.name],
*fun.lambda.env, *fun.lambda.fun); *fun.lambda.env, *fun.lambda.fun);
} }
} }

View file

@ -231,6 +231,11 @@ public:
/* Decode a path encoded by `encodePath()`. */ /* Decode a path encoded by `encodePath()`. */
SourcePath decodePath(std::string_view s, PosIdx pos = noPos); SourcePath decodePath(std::string_view s, PosIdx pos = noPos);
/* Decode all virtual paths in a string, i.e. all
/__virtual__/... substrings are replaced by the corresponding
input accessor. */
std::string decodePaths(std::string_view s);
/* Allow access to a path. */ /* Allow access to a path. */
void allowPath(const Path & path); void allowPath(const Path & path);

View file

@ -63,4 +63,34 @@ SourcePath EvalState::decodePath(std::string_view s, PosIdx pos)
return {rootFS, CanonPath(s)}; return {rootFS, CanonPath(s)};
} }
std::string EvalState::decodePaths(std::string_view s)
{
std::string res;
size_t pos = 0;
while (true) {
auto m = s.find(marker, pos);
if (m == s.npos) {
res.append(s.substr(pos));
return res;
}
res.append(s.substr(pos, m - pos));
auto end = s.find_first_of(" \n\r\t'\":", m);
if (end == s.npos) end = s.size();
try {
auto path = decodePath(s.substr(m, end - m), noPos);
res.append(path.to_string());
} catch (...) {
throw;
res.append(s.substr(pos, end - m));
}
pos = end;
}
}
} }

View file

@ -770,7 +770,7 @@ static RegisterPrimOp primop_abort({
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v) .fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
{ {
PathSet context; PathSet context;
auto s = state.coerceToString(pos, *args[0], context).toOwned(); auto s = state.decodePaths(*state.coerceToString(pos, *args[0], context));
state.debugThrowLastTrace(Abort("evaluation aborted with the following error message: '%1%'", s)); state.debugThrowLastTrace(Abort("evaluation aborted with the following error message: '%1%'", s));
} }
}); });
@ -788,7 +788,7 @@ static RegisterPrimOp primop_throw({
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v) .fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
{ {
PathSet context; PathSet context;
auto s = state.coerceToString(pos, *args[0], context).toOwned(); auto s = state.decodePaths(*state.coerceToString(pos, *args[0], context));
state.debugThrowLastTrace(ThrownError(s)); state.debugThrowLastTrace(ThrownError(s));
} }
}); });
@ -800,7 +800,7 @@ static void prim_addErrorContext(EvalState & state, const PosIdx pos, Value * *
v = *args[1]; v = *args[1];
} catch (Error & e) { } catch (Error & e) {
PathSet context; PathSet context;
e.addTrace(nullptr, state.coerceToString(pos, *args[0], context).toOwned()); e.addTrace(nullptr, state.decodePaths(*state.coerceToString(pos, *args[0], context)));
throw; throw;
} }
} }