From 614c77f453020ffbe3970d49dc3f624712f1cea7 Mon Sep 17 00:00:00 2001
From: Christoph Lehmann <christoph.lehmann@ufz.de>
Date: Fri, 17 Jun 2016 20:44:10 +0200
Subject: [PATCH] [BL] assert that ConfigTree dtor is nothrow

---
 BaseLib/ConfigTree.cpp | 25 ++++++++++++++++++++++++-
 BaseLib/ConfigTree.h   |  6 +++++-
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/BaseLib/ConfigTree.cpp b/BaseLib/ConfigTree.cpp
index e74dda59ff5..fff16136b25 100644
--- a/BaseLib/ConfigTree.cpp
+++ b/BaseLib/ConfigTree.cpp
@@ -9,6 +9,7 @@
 
 #include "ConfigTree.h"
 
+#include <forward_list>
 #include <logog/include/logog.hpp>
 
 #include "Error.h"
@@ -18,6 +19,10 @@
 template class boost::property_tree::basic_ptree<std::string, std::string,
                                                  std::less<std::string>>;
 
+//! Collects swallowed error messages raised by the check during destruction of
+//! ConfigTree instances.
+static std::forward_list<std::string> configtree_destructor_error_messages;
+
 namespace BaseLib
 {
 
@@ -65,8 +70,11 @@ ConfigTree(ConfigTree && other)
 
 ConfigTree::~ConfigTree()
 {
-    if (!std::uncaught_exception())
+    try {
         checkAndInvalidate();
+    } catch (std::exception& e) {
+        configtree_destructor_error_messages.push_front(e.what());
+    }
 }
 
 ConfigTree&
@@ -220,6 +228,21 @@ void ConfigTree::onwarning(const std::string& filename, const std::string& path,
          filename.c_str(), path.c_str(), message.c_str());
 }
 
+void ConfigTree::assertNoSwallowedErrors()
+{
+    if (configtree_destructor_error_messages.empty())
+        return;
+
+    ERR("ConfigTree: There have been errors when parsing the configuration "
+        "file(s):");
+
+    for (auto const& msg : configtree_destructor_error_messages) {
+        ERR("%s", msg.c_str());
+    }
+
+    OGS_FATAL("There have been errors when parsing the configuration file(s).");
+}
+
 std::string ConfigTree::shortString(const std::string &s)
 {
     const std::size_t maxlen = 100;
diff --git a/BaseLib/ConfigTree.h b/BaseLib/ConfigTree.h
index 74ccd116917..6157d57b165 100644
--- a/BaseLib/ConfigTree.h
+++ b/BaseLib/ConfigTree.h
@@ -493,6 +493,8 @@ public:
 
     //! The destructor performs the check if all nodes at the current level of the tree
     //! have been read.
+    //! Errors raised by the check are swallowed. Use assertNoSwallowedErrors()
+    //! manually to check for those.
     ~ConfigTree();
 
     //! Default error callback function
@@ -505,6 +507,9 @@ public:
     static void onwarning(std::string const& filename, std::string const& path,
                           std::string const& message);
 
+    //! Asserts that there have not been any errors reported in the destructor.
+    static void assertNoSwallowedErrors();
+
 private:
     //! Default implementation of reading a value of type T.
     template<typename T> boost::optional<T>
@@ -514,7 +519,6 @@ private:
     template<typename T> boost::optional<std::vector<T>>
     getConfigParameterOptionalImpl(std::string const& param, std::vector<T>*) const;
 
-private:
     struct CountType
     {
         int count;
-- 
GitLab