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

Add tests for error traces, and fixes

This commit is contained in:
Guillaume Maudoux 2022-11-29 00:25:36 +01:00
parent e4726a0c79
commit ca7c5e08c1
8 changed files with 1377 additions and 140 deletions

View file

@ -11,7 +11,9 @@
#include <algorithm>
#include <chrono>
#include <iostream>
#include <cstring>
#include <optional>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
@ -1927,7 +1929,9 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
/* skip canonization of first path, which would only be not
canonized in the first place if it's coming from a ./${foo} type
path */
auto part = state.coerceToString(i_pos, vTmp, context, false, firstType == nString, !first, "while evaluating a path segment");
auto part = state.coerceToString(i_pos, vTmp, context,
"while evaluating a path segment",
false, firstType == nString, !first);
sSize += part->size();
s.emplace_back(std::move(part));
}
@ -2123,15 +2127,16 @@ std::optional<std::string> EvalState::tryAttrsToString(const PosIdx pos, Value &
if (i != v.attrs->end()) {
Value v1;
callFunction(*i->value, v, v1, pos);
return coerceToString(pos, v1, context, coerceMore, copyToStore,
"while evaluating the result of the `toString` attribute").toOwned();
return coerceToString(pos, v1, context,
"while evaluating the result of the `toString` attribute",
coerceMore, copyToStore).toOwned();
}
return {};
}
BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet & context,
bool coerceMore, bool copyToStore, bool canonicalizePath, std::string_view errorCtx)
BackedStringView EvalState::coerceToString(const PosIdx pos, Value &v, PathSet &context,
std::string_view errorCtx, bool coerceMore, bool copyToStore, bool canonicalizePath)
{
forceValue(v, pos);
@ -2154,13 +2159,23 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet
if (maybeString)
return std::move(*maybeString);
auto i = v.attrs->find(sOutPath);
if (i == v.attrs->end())
error("cannot coerce a set to a string", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
return coerceToString(pos, *i->value, context, coerceMore, copyToStore, canonicalizePath, errorCtx);
if (i == v.attrs->end()) {
error("cannot coerce %1% to a string", showType(v))
.withTrace(pos, errorCtx)
.debugThrow<TypeError>();
}
return coerceToString(pos, *i->value, context, errorCtx,
coerceMore, copyToStore, canonicalizePath);
}
if (v.type() == nExternal)
return v.external->coerceToString(positions[pos], context, coerceMore, copyToStore, errorCtx);
if (v.type() == nExternal) {
try {
return v.external->coerceToString(positions[pos], context, coerceMore, copyToStore);
} catch (Error & e) {
e.addTrace(nullptr, errorCtx);
throw;
}
}
if (coerceMore) {
/* Note that `false' is represented as an empty string for
@ -2175,8 +2190,9 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet
std::string result;
for (auto [n, v2] : enumerate(v.listItems())) {
try {
result += *coerceToString(noPos, *v2, context, coerceMore, copyToStore, canonicalizePath,
"while evaluating one element of the list");
result += *coerceToString(noPos, *v2, context,
"while evaluating one element of the list",
coerceMore, copyToStore, canonicalizePath);
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
throw;
@ -2190,7 +2206,9 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet
}
}
error("cannot coerce %1% to a string", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
error("cannot coerce %1% to a string", showType(v))
.withTrace(pos, errorCtx)
.debugThrow<TypeError>();
}
@ -2220,7 +2238,7 @@ StorePath EvalState::copyPathToStore(PathSet & context, const Path & path)
Path EvalState::coerceToPath(const PosIdx pos, Value & v, PathSet & context, std::string_view errorCtx)
{
auto path = coerceToString(pos, v, context, false, false, true, errorCtx).toOwned();
auto path = coerceToString(pos, v, context, errorCtx, false, false, true).toOwned();
if (path == "" || path[0] != '/')
error("string '%1%' doesn't represent an absolute path", path).withTrace(pos, errorCtx).debugThrow<EvalError>();
return path;
@ -2229,7 +2247,7 @@ Path EvalState::coerceToPath(const PosIdx pos, Value & v, PathSet & context, std
StorePath EvalState::coerceToStorePath(const PosIdx pos, Value & v, PathSet & context, std::string_view errorCtx)
{
auto path = coerceToString(pos, v, context, false, false, true, errorCtx).toOwned();
auto path = coerceToString(pos, v, context, errorCtx, false, false, true).toOwned();
if (auto storePath = store->maybeParseStorePath(path))
return *storePath;
error("path '%1%' is not in the Nix store", path).withTrace(pos, errorCtx).debugThrow<EvalError>();
@ -2433,13 +2451,11 @@ void EvalState::printStats()
}
std::string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore, std::string_view errorCtx) const
std::string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const
{
auto e = TypeError({
throw TypeError({
.msg = hintfmt("cannot coerce %1% to a string", showType())
});
e.addTrace(pos, errorCtx);
throw e;
}