forked from lix-project/lix
Fix exception handling around realisePath()
This no longer worked correctly because 'path' is uninitialised when an exception occurs, leading to errors like … while importing '' at /nix/store/rrzz5b1pshvzh1437ac9nkl06br81lkv-source/flake.nix:352:13: So move the adding of the error context into realisePath().
This commit is contained in:
parent
e85cf34ea3
commit
128098040b
|
@ -102,17 +102,30 @@ static Path realisePath(EvalState & state, const Pos & pos, Value & v, const Rea
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
|
|
||||||
Path path = flags.requireAbsolutePath
|
auto path = [&]()
|
||||||
? state.coerceToPath(pos, v, context)
|
{
|
||||||
: state.coerceToString(pos, v, context, false, false);
|
try {
|
||||||
|
return flags.requireAbsolutePath
|
||||||
|
? state.coerceToPath(pos, v, context)
|
||||||
|
: state.coerceToString(pos, v, context, false, false);
|
||||||
|
} catch (Error & e) {
|
||||||
|
e.addTrace(pos, "while realising the context of a path");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
StringMap rewrites = state.realiseContext(context);
|
try {
|
||||||
|
StringMap rewrites = state.realiseContext(context);
|
||||||
|
|
||||||
auto realPath = state.toRealPath(rewriteStrings(path, rewrites), context);
|
auto realPath = state.toRealPath(rewriteStrings(path, rewrites), context);
|
||||||
|
|
||||||
return flags.checkForPureEval
|
return flags.checkForPureEval
|
||||||
? state.checkSourcePath(realPath)
|
? state.checkSourcePath(realPath)
|
||||||
: realPath;
|
: realPath;
|
||||||
|
} catch (Error & e) {
|
||||||
|
e.addTrace(pos, "while realising the context of path '%s'", path);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add and attribute to the given attribute map from the output name to
|
/* Add and attribute to the given attribute map from the output name to
|
||||||
|
@ -150,18 +163,7 @@ static void mkOutputString(
|
||||||
argument. */
|
argument. */
|
||||||
static void import(EvalState & state, const Pos & pos, Value & vPath, Value * vScope, Value & v)
|
static void import(EvalState & state, const Pos & pos, Value & vPath, Value * vScope, Value & v)
|
||||||
{
|
{
|
||||||
Path path;
|
auto path = realisePath(state, pos, vPath);
|
||||||
try {
|
|
||||||
path = realisePath(state, pos, vPath);
|
|
||||||
} catch (InvalidPathError & e) {
|
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt("cannot import '%1%', since path '%2%' is not valid", path, e.path),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
} catch (Error & e) {
|
|
||||||
e.addTrace(pos, "while importing '%s'", path);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
auto isValidDerivationInStore = [&]() -> std::optional<StorePath> {
|
auto isValidDerivationInStore = [&]() -> std::optional<StorePath> {
|
||||||
|
@ -314,18 +316,7 @@ extern "C" typedef void (*ValueInitializer)(EvalState & state, Value & v);
|
||||||
/* Load a ValueInitializer from a DSO and return whatever it initializes */
|
/* Load a ValueInitializer from a DSO and return whatever it initializes */
|
||||||
void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Path path;
|
auto path = realisePath(state, pos, *args[0]);
|
||||||
try {
|
|
||||||
path = realisePath(state, pos, *args[0]);
|
|
||||||
} catch (InvalidPathError & e) {
|
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt("cannot import '%1%', since path '%2%' is not valid", path, e.path),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
} catch (Error & e) {
|
|
||||||
e.addTrace(pos, "while importing '%s'", path);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
string sym = state.forceStringNoCtx(*args[1], pos);
|
string sym = state.forceStringNoCtx(*args[1], pos);
|
||||||
|
|
||||||
|
@ -1379,22 +1370,12 @@ static RegisterPrimOp primop_storePath({
|
||||||
|
|
||||||
static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Path path;
|
/* We don’t check the path right now, because we don’t want to
|
||||||
try {
|
throw if the path isn’t allowed, but just return false (and we
|
||||||
// We don’t check the path right now, because we don’t want to throw if
|
can’t just catch the exception here because we still want to
|
||||||
// the path isn’t allowed, but just return false
|
throw if something in the evaluation of `*args[0]` tries to
|
||||||
// (and we can’t just catch the exception here because we still want to
|
access an unauthorized path). */
|
||||||
// throw if something in the evaluation of `*args[0]` tries to access an
|
auto path = realisePath(state, pos, *args[0], { .checkForPureEval = false });
|
||||||
// unauthorized path)
|
|
||||||
path = realisePath(state, pos, *args[0], { .checkForPureEval = false });
|
|
||||||
} catch (InvalidPathError & e) {
|
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt(
|
|
||||||
"cannot check the existence of '%1%', since path '%2%' is not valid",
|
|
||||||
path, e.path),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
v.mkBool(pathExists(state.checkSourcePath(path)));
|
v.mkBool(pathExists(state.checkSourcePath(path)));
|
||||||
|
@ -1460,15 +1441,7 @@ static RegisterPrimOp primop_dirOf({
|
||||||
/* Return the contents of a file as a string. */
|
/* Return the contents of a file as a string. */
|
||||||
static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Path path;
|
auto path = realisePath(state, pos, *args[0]);
|
||||||
try {
|
|
||||||
path = realisePath(state, pos, *args[0]);
|
|
||||||
} catch (InvalidPathError & e) {
|
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt("cannot read '%1%', since path '%2%' is not valid", path, e.path),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
}
|
|
||||||
string s = readFile(path);
|
string s = readFile(path);
|
||||||
if (s.find((char) 0) != string::npos)
|
if (s.find((char) 0) != string::npos)
|
||||||
throw Error("the contents of the file '%1%' cannot be represented as a Nix string", path);
|
throw Error("the contents of the file '%1%' cannot be represented as a Nix string", path);
|
||||||
|
@ -1512,16 +1485,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
pos
|
pos
|
||||||
);
|
);
|
||||||
|
|
||||||
Path path;
|
auto path = realisePath(state, pos, *i->value, { .requireAbsolutePath = false });
|
||||||
|
|
||||||
try {
|
|
||||||
path = realisePath(state, pos, *i->value, { .requireAbsolutePath = false });
|
|
||||||
} catch (InvalidPathError & e) {
|
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt("cannot find '%1%', since path '%2%' is not valid", path, e.path),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
searchPath.emplace_back(prefix, path);
|
searchPath.emplace_back(prefix, path);
|
||||||
}
|
}
|
||||||
|
@ -1548,12 +1512,7 @@ static void prim_hashFile(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
.errPos = pos
|
.errPos = pos
|
||||||
});
|
});
|
||||||
|
|
||||||
Path path;
|
auto path = realisePath(state, pos, *args[1]);
|
||||||
try {
|
|
||||||
path = realisePath(state, pos, *args[1]);
|
|
||||||
} catch (InvalidPathError & e) {
|
|
||||||
throw EvalError("cannot read '%s' since path '%s' is not valid, at %s", path, e.path, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
v.mkString(hashFile(*ht, path).to_string(Base16, false));
|
v.mkString(hashFile(*ht, path).to_string(Base16, false));
|
||||||
}
|
}
|
||||||
|
@ -1572,15 +1531,7 @@ static RegisterPrimOp primop_hashFile({
|
||||||
/* Read a directory (without . or ..) */
|
/* Read a directory (without . or ..) */
|
||||||
static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Path path;
|
auto path = realisePath(state, pos, *args[0]);
|
||||||
try {
|
|
||||||
path = realisePath(state, pos, *args[0]);
|
|
||||||
} catch (InvalidPathError & e) {
|
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt("cannot read '%1%', since path '%2%' is not valid", path, e.path),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
DirEntries entries = readDirectory(path);
|
DirEntries entries = readDirectory(path);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue