From 6228b6b9501527ed20da50fe7dc1c28f730c120d Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Tue, 20 Dec 2022 12:06:27 +0100 Subject: [PATCH] Discuss re-entrant errors and design --- src/libexpr/eval.hh | 3 +++ src/libexpr/tests/error_traces.cc | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 1d2e5005b..e4d5906bd 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -203,6 +203,9 @@ public: throw std::move(error); } + // This is dangerous, but gets in line with the idea that error creation and + // throwing should not allocate on the stack of hot functions. + // as long as errors are immediately thrown, it works. ErrorBuilder * errorBuilder; template diff --git a/src/libexpr/tests/error_traces.cc b/src/libexpr/tests/error_traces.cc index 7d6bd2111..5e2213f69 100644 --- a/src/libexpr/tests/error_traces.cc +++ b/src/libexpr/tests/error_traces.cc @@ -45,6 +45,21 @@ namespace nix { ); } + TEST_F(ErrorTraceTest, NestedThrows) { + try { + state.error("Not much").withTrace(noPos, "No more").debugThrow(); + } catch (BaseError & e) { + try { + state.error("Not much more").debugThrow(); + } catch (Error & e2) { + e.addTrace(state.positions[noPos], "Something", ""); + //e2.addTrace(state.positions[noPos], "Something", ""); + ASSERT_TRUE(e.info().traces.size() == 2); + ASSERT_TRUE(e2.info().traces.size() == 0); + ASSERT_FALSE(&e.info() == &e2.info()); + } + } + } #define ASSERT_TRACE1(args, type, message) \ ASSERT_THROW( \