From 9ab808c92613b59a72a4d15cfda1adb6aa523e28 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 25 Jun 2020 09:23:12 -0600 Subject: [PATCH] showTrace flag for ErrorInfo; showTrace test. --- src/libmain/shared.cc | 4 +-- src/libutil/error.cc | 65 +++++++++++++++++++----------------- src/libutil/error.hh | 1 + src/libutil/tests/logging.cc | 25 ++++++++++++++ 4 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index e1b1cd4fc..7514b19d2 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -303,6 +303,7 @@ int handleExceptions(const string & programName, std::function fun) ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this ErrorInfo::programName = baseNameOf(programName); + ErrorInfo::showTrace = settings.showTrace; string error = ANSI_RED "error:" ANSI_NORMAL " "; try { @@ -323,9 +324,6 @@ int handleExceptions(const string & programName, std::function fun) printError("Try '%1% --help' for more information.", programName); return 1; } catch (BaseError & e) { - // TODO showTrace as argument, or have calcWhat check settings? - // if (settings.showTrace && e.prefix() != "") - // printError(e.prefix()); logError(e.info()); // TODO fix to detect non-empty trace here. if (e.hasTrace() && !settings.showTrace) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 1185a0204..10a5300cb 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -34,6 +34,7 @@ const string& BaseError::calcWhat() const } std::optional ErrorInfo::programName = std::nullopt; +bool ErrorInfo::showTrace = false; std::ostream& operator<<(std::ostream &os, const hintformat &hf) { @@ -325,42 +326,44 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) } // traces - for (auto iter = einfo.traces.rbegin(); iter != einfo.traces.rend(); ++iter) - { - try { - if (nl) - out << std::endl << prefix; + if (ErrorInfo::showTrace) { + for (auto iter = einfo.traces.rbegin(); iter != einfo.traces.rend(); ++iter) + { + try { + if (nl) + out << std::endl << prefix; - const string tracetitle(" show-trace output "); + const string tracetitle(" show-trace output "); - int fill = errwidth - tracetitle.length(); - int lw = 0; - int rw = 0; - const int min_dashes = 3; - if (fill > min_dashes * 2) { - if (fill % 2 != 0) { - lw = fill / 2; - rw = lw + 1; + int fill = errwidth - tracetitle.length(); + int lw = 0; + int rw = 0; + const int min_dashes = 3; + if (fill > min_dashes * 2) { + if (fill % 2 != 0) { + lw = fill / 2; + rw = lw + 1; + } + else + { + lw = rw = fill / 2; + } } else - { - lw = rw = fill / 2; - } + lw = rw = min_dashes; + + out << ANSI_BLUE << std::string(lw, '-') << tracetitle << std::string(rw, '-') << std::endl << prefix; + out << iter->hint.str() << std::endl; + + auto pos = *iter->pos; + printAtPos(prefix, pos, out); + nl = true; + auto loc = getCodeLines(pos); + if (loc.has_value()) + printCodeLines(out, prefix, pos, *loc); + } catch(const std::bad_optional_access& e) { + out << iter->hint.str() << std::endl; } - else - lw = rw = min_dashes; - - out << ANSI_BLUE << std::string(lw, '-') << tracetitle << std::string(rw, '-') << std::endl << prefix; - out << iter->hint.str() << std::endl; - - auto pos = *iter->pos; - printAtPos(prefix, pos, out); - nl = true; - auto loc = getCodeLines(pos); - if (loc.has_value()) - printCodeLines(out, prefix, pos, *loc); - } catch(const std::bad_optional_access& e) { - out << iter->hint.str() << std::endl; } } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index d79ff8f8c..dcde28453 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -107,6 +107,7 @@ struct ErrorInfo { std::list traces; static std::optional programName; + static bool showTrace; }; std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); diff --git a/src/libutil/tests/logging.cc b/src/libutil/tests/logging.cc index 6d0431133..7531d6c7a 100644 --- a/src/libutil/tests/logging.cc +++ b/src/libutil/tests/logging.cc @@ -251,6 +251,7 @@ namespace nix { TEST(addTrace, showTracesWithShowTrace) { SymbolTable testTable; + ErrorInfo::showTrace = true; auto problem_file = testTable.create(test_file); auto oneliner_file = testTable.create(one_liner); @@ -272,6 +273,30 @@ namespace nix { 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 command line argument\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 output ---\nwhile 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 1| this is the other problem line of code\n | \x1B[31;1m^\x1B[0m\n"); } + TEST(addTrace, hideTracesWithoutShowTrace) { + SymbolTable testTable; + ErrorInfo::showTrace = false; + auto problem_file = testTable.create(test_file); + + auto oneliner_file = testTable.create(one_liner); + + auto e = AssertionError(ErrorInfo { + .name = "wat", + .description = "a well-known problem occurred", + .hint = hintfmt("it has been %1% days since our last error", "zero"), + .errPos = Pos(foString, problem_file, 2, 13), + }); + + e.addTrace(Pos(foStdin, oneliner_file, 1, 19), "while trying to compute %1%", 42); + + testing::internal::CaptureStderr(); + + 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 command line argument\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"); + } + /* ---------------------------------------------------------------------------- * hintfmt * --------------------------------------------------------------------------*/