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