diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 6b6b268a2..78e2a5ea2 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -187,6 +187,7 @@ void printCodeLines(std::ostream &out, void printAtPos(const string &prefix, const ErrPos &pos, std::ostream &out) { + if (pos) { switch (pos.origin) { case foFile: { @@ -290,7 +291,7 @@ std::ostream& showErrorInfo(std::ostream &out, const ErrorInfo &einfo, bool show einfo.programName.value_or("")); bool nl = false; // intersperse newline between sections. - if (einfo.errPos.has_value()) { + if (einfo.errPos.has_value() && (*einfo.errPos)) { out << prefix << std::endl; printAtPos(prefix, *einfo.errPos, out); nl = true; @@ -355,17 +356,20 @@ std::ostream& showErrorInfo(std::ostream &out, const ErrorInfo &einfo, bool show { try { out << std::endl << prefix; - out << ANSI_BLUE << "trace: " << ANSI_NORMAL << iter->hint.str() << std::endl; + out << ANSI_BLUE << "trace: " << ANSI_NORMAL << iter->hint.str(); - auto pos = *iter->pos; - printAtPos(prefix, pos, out); nl = true; - auto loc = getCodeLines(pos); - if (loc.has_value()) - { - out << std::endl; - printCodeLines(out, prefix, pos, *loc); - out << std::endl; + auto pos = *iter->pos; + if (pos) { + out << std::endl << prefix; + printAtPos(prefix, pos, out); + auto loc = getCodeLines(pos); + if (loc.has_value()) + { + out << std::endl << prefix; + printCodeLines(out, prefix, pos, *loc); + out << std::endl << prefix; + } } } catch(const std::bad_optional_access& e) { out << iter->hint.str() << std::endl; diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 504f5fb52..7a58527b8 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -84,6 +84,7 @@ public: log(ei.level, oss.str()); } + void startActivity(ActivityId act, Verbosity lvl, ActivityType type, const std::string & s, const Fields & fields, ActivityId parent) diff --git a/src/libutil/tests/logging.cc b/src/libutil/tests/logging.cc index a73c1f8d9..4ebc3a3bf 100644 --- a/src/libutil/tests/logging.cc +++ b/src/libutil/tests/logging.cc @@ -263,6 +263,7 @@ namespace nix { }); e.addTrace(Pos(foStdin, oneliner_file, 1, 19), "while trying to compute %1%", 42); + e.addTrace(std::nullopt, "while doing something without a %1%", "pos"); testing::internal::CaptureStderr(); @@ -271,7 +272,7 @@ namespace nix { logError(e.info()); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- AssertionError --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from string\x1B[0m\n\na well-known problem occurred\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nit has been \x1B[33;1mzero\x1B[0m days since our last error\n\x1B[34;1m---- show-trace ----\x1B[0m\n\x1B[34;1mtrace: \x1B[0mwhile trying to compute \x1B[33;1m42\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(1:19)\x1B[34;1m from stdin\x1B[0m\n\n 1| this is the other problem line of code\n | \x1B[31;1m^\x1B[0m\n\n"); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- AssertionError --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from string\x1B[0m\n\na well-known problem occurred\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nit has been \x1B[33;1mzero\x1B[0m days since our last error\n\x1B[34;1m---- show-trace ----\x1B[0m\n\x1B[34;1mtrace: \x1B[0mwhile trying to compute \x1B[33;1m42\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(1:19)\x1B[34;1m from stdin\x1B[0m\n\n 1| this is the other problem line of code\n | \x1B[31;1m^\x1B[0m\n\n\x1B[34;1mtrace: \x1B[0mwhile doing something without a \x1B[33;1mpos\x1B[0m\n"); } TEST(addTrace, hideTracesWithoutShowTrace) { @@ -288,6 +289,7 @@ namespace nix { }); e.addTrace(Pos(foStdin, oneliner_file, 1, 19), "while trying to compute %1%", 42); + e.addTrace(std::nullopt, "while doing something without a %1%", "pos"); testing::internal::CaptureStderr();