1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 10:41:16 +02:00

Print the value in error: cannot coerce messages

This extends the `error: cannot coerce a TYPE to a string` message
to print the value that could not be coerced. This helps with debugging
by making it easier to track down where the value is being produced
from, especially in errors with deep or unhelpful stack traces.
This commit is contained in:
Rebecca Turner 2023-12-06 12:42:53 -08:00
parent 5f72a97092
commit 83bb494a30
No known key found for this signature in database
10 changed files with 68 additions and 31 deletions

View file

@ -2255,7 +2255,9 @@ BackedStringView EvalState::coerceToString(
return std::move(*maybeString);
auto i = v.attrs->find(sOutPath);
if (i == v.attrs->end()) {
error("cannot coerce %1% to a string", showType(v))
error("cannot coerce %1% to a string: %2%",
showType(v),
ValuePrinter(*this, v, errorPrintOptions))
.withTrace(pos, errorCtx)
.debugThrow<TypeError>();
}
@ -2301,7 +2303,9 @@ BackedStringView EvalState::coerceToString(
}
}
error("cannot coerce %1% to a string", showType(v))
error("cannot coerce %1% to a string: %2%",
showType(v),
ValuePrinter(*this, v, errorPrintOptions))
.withTrace(pos, errorCtx)
.debugThrow<TypeError>();
}
@ -2661,7 +2665,7 @@ void EvalState::printStatistics()
std::string ExternalValueBase::coerceToString(const Pos & pos, NixStringContext & context, bool copyMore, bool copyToStore) const
{
throw TypeError({
.msg = hintfmt("cannot coerce %1% to a string", showType())
.msg = hintfmt("cannot coerce %1% to a string: %2%", showType(), *this)
});
}

View file

@ -36,11 +36,17 @@ struct PrintOptions
*/
size_t maxDepth = std::numeric_limits<size_t>::max();
/**
* Maximum number of attributes in an attribute set to print.
* Maximum number of attributes in attribute sets to print.
*
* Note that this is a limit for the entire print invocation, not for each
* attribute set encountered.
*/
size_t maxAttrs = std::numeric_limits<size_t>::max();
/**
* Maximum number of list items to print.
*
* Note that this is a limit for the entire print invocation, not for each
* list encountered.
*/
size_t maxListItems = std::numeric_limits<size_t>::max();
/**

View file

@ -20,7 +20,7 @@ void printElided(
{
if (ansiColors)
output << ANSI_FAINT;
output << " «";
output << "«";
pluralize(output, value, single, plural);
output << " elided»";
if (ansiColors)
@ -37,7 +37,7 @@ printLiteralString(std::ostream & str, const std::string_view string, size_t max
str << "\"";
for (auto i = string.begin(); i != string.end(); ++i) {
if (charsPrinted >= maxLength) {
str << "\"";
str << "\" ";
printElided(str, string.length() - charsPrinted, "byte", "bytes", ansiColors);
return str;
}
@ -161,6 +161,8 @@ private:
EvalState & state;
PrintOptions options;
std::optional<ValuesSeen> seen;
size_t attrsPrinted = 0;
size_t listItemsPrinted = 0;
void printRepeated()
{
@ -279,7 +281,6 @@ private:
else
std::sort(sorted.begin(), sorted.end(), ImportantFirstAttrNameCmp());
size_t attrsPrinted = 0;
for (auto & i : sorted) {
if (attrsPrinted >= options.maxAttrs) {
printElided(sorted.size() - attrsPrinted, "attribute", "attributes");
@ -307,7 +308,6 @@ private:
output << "[ ";
if (depth < options.maxDepth) {
size_t listItemsPrinted = 0;
for (auto elem : v.listItems()) {
if (listItemsPrinted >= options.maxListItems) {
printElided(v.listSize() - listItemsPrinted, "item", "items");
@ -486,6 +486,9 @@ public:
void print(Value & v)
{
attrsPrinted = 0;
listItemsPrinted = 0;
if (options.trackRepeated) {
seen.emplace();
} else {