From a31c20e62ae739cda1395e0253bda87c69896853 Mon Sep 17 00:00:00 2001 From: Moritz Bruder Date: Sat, 24 Feb 2018 12:55:08 +0100 Subject: [PATCH] Improve exception error messages * Inherit exceptions from std::runtime_error * Refactor error message functions * Refactor path construction functions * Add path to error messages --- lib/libconfig.h++ | 41 ++++---- lib/libconfigcpp.c++ | 229 +++++++++++++++++++++++++++++-------------- 2 files changed, 176 insertions(+), 94 deletions(-) diff --git a/lib/libconfig.h++ b/lib/libconfig.h++ index 696454a..dd078d8 100644 --- a/lib/libconfig.h++ +++ b/lib/libconfig.h++ @@ -24,7 +24,7 @@ #define __libconfig_hpp #include -#include +#include #include #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) @@ -54,7 +54,16 @@ struct config_setting_t; // fwd decl namespace libconfig { -class LIBCONFIGXX_API ConfigException : public std::exception { }; +struct LIBCONFIGXX_API ConfigException : public std::runtime_error +{ + ConfigException(); + ConfigException(std::string const &message); + + ConfigException(ConfigException const &other); + ConfigException& operator=(ConfigException const &other); + + virtual ~ConfigException() LIBCONFIGXX_NOEXCEPT; +}; class Setting; // fwd decl class SettingIterator; @@ -62,6 +71,14 @@ class SettingConstIterator; class LIBCONFIGXX_API SettingException : public ConfigException { + + protected: + + SettingException(char const *derivedType, const Setting &setting); + SettingException(char const *derivedType, const Setting &setting, int idx); + SettingException(char const *derivedType, const Setting &setting, const char *name); + SettingException(char const *derivedType, std::string path); + public: SettingException(const Setting &setting); @@ -74,13 +91,11 @@ class LIBCONFIGXX_API SettingException : public ConfigException virtual ~SettingException() LIBCONFIGXX_NOEXCEPT; - const char *getPath() const; - - virtual const char *what() const LIBCONFIGXX_NOEXCEPT; + std::string const & getPath() const; private: - char *_path; + std::string _path; }; class LIBCONFIGXX_API SettingTypeException : public SettingException @@ -90,8 +105,6 @@ class LIBCONFIGXX_API SettingTypeException : public SettingException SettingTypeException(const Setting &setting); SettingTypeException(const Setting &setting, int idx); SettingTypeException(const Setting &setting, const char *name); - - virtual const char *what() const LIBCONFIGXX_NOEXCEPT; }; class LIBCONFIGXX_API SettingNotFoundException : public SettingException @@ -101,8 +114,6 @@ class LIBCONFIGXX_API SettingNotFoundException : public SettingException SettingNotFoundException(const char *path); SettingNotFoundException(const Setting &setting, int idx); SettingNotFoundException(const Setting &setting, const char *name); - - virtual const char *what() const LIBCONFIGXX_NOEXCEPT; }; class LIBCONFIGXX_API SettingNameException : public SettingException @@ -110,15 +121,11 @@ class LIBCONFIGXX_API SettingNameException : public SettingException public: SettingNameException(const Setting &setting, const char *name); - - virtual const char *what() const LIBCONFIGXX_NOEXCEPT; }; -class LIBCONFIGXX_API FileIOException : public ConfigException +struct LIBCONFIGXX_API FileIOException : public ConfigException { - public: - - virtual const char *what() const LIBCONFIGXX_NOEXCEPT; + FileIOException(); }; class LIBCONFIGXX_API ParseException : public ConfigException @@ -140,8 +147,6 @@ class LIBCONFIGXX_API ParseException : public ConfigException inline const char *getError() const { return(_error); } - virtual const char *what() const LIBCONFIGXX_NOEXCEPT; - private: const char *_file; diff --git a/lib/libconfigcpp.c++ b/lib/libconfigcpp.c++ index 9cdee4d..6b06729 100644 --- a/lib/libconfigcpp.c++ +++ b/lib/libconfigcpp.c++ @@ -48,8 +48,62 @@ static const char **__include_func(config_t *config, // --------------------------------------------------------------------------- +ConfigException::ConfigException() + : std::runtime_error("") +{ +} + +// --------------------------------------------------------------------------- + +ConfigException::ConfigException(std::string const &errorMessage) + : std::runtime_error(errorMessage) +{ +} + +// --------------------------------------------------------------------------- + +ConfigException::ConfigException(ConfigException const &other) + : std::runtime_error(other.what()) +{ +} + +// --------------------------------------------------------------------------- + +ConfigException& ConfigException::operator=(ConfigException const &other) +{ + std::runtime_error::operator=(other); + return(*this); +} + +// --------------------------------------------------------------------------- + +ConfigException::~ConfigException() LIBCONFIGXX_NOEXCEPT +{ +} + +// --------------------------------------------------------------------------- + +static std::string __makeParseExceptionErrorString(const char *file, + int line, + const char *error) +{ + std::stringstream sstr; + + sstr << "parse exception: "; + + if (file != 0) + sstr << "in " << file << ", "; + + sstr << "at line " << line << ": " << error; + + return sstr.str(); +} + +// --------------------------------------------------------------------------- + ParseException::ParseException(const char *file, int line, const char *error) - : _file(file ? ::strdup(file) : NULL), _line(line), _error(error) + : ConfigException(__makeParseExceptionErrorString(file, line, error)), + _file(file ? ::strdup(file) : NULL), _line(line), _error(error) { } @@ -72,13 +126,6 @@ ParseException::~ParseException() LIBCONFIGXX_NOEXCEPT // --------------------------------------------------------------------------- -const char *ParseException::what() const LIBCONFIGXX_NOEXCEPT -{ - return("ParseException"); -} - -// --------------------------------------------------------------------------- - static int __toTypeCode(Setting::Type type) { int typecode; @@ -126,182 +173,212 @@ static int __toTypeCode(Setting::Type type) // --------------------------------------------------------------------------- -static void __constructPath(const Setting &setting, - std::stringstream &path) +static void __writeSettingPath(const Setting &setting, std::ostream &o) { // head recursion to print path from root to target - if(! setting.isRoot()) + if(!setting.isRoot()) { - __constructPath(setting.getParent(), path); - if(path.tellp() > 0) - path << '.'; - - const char *name = setting.getName(); - if(name) - path << name; - else - path << '[' << setting.getIndex() << ']'; + __writeSettingPath(setting.getParent(), o); + o << '.'; } + const char *name = setting.getName(); + + if(name) + o << name; + else + o << '[' << setting.getIndex() << ']'; } // --------------------------------------------------------------------------- -SettingException::SettingException(const Setting &setting) +static std::string __constructSettingPath(const Setting &setting) { - std::stringstream sstr; - __constructPath(setting, sstr); + std::stringstream ss; + __writeSettingPath(setting, ss); + return ss.str(); +} - _path = ::strdup(sstr.str().c_str()); +// --------------------------------------------------------------------------- + +static std::string __constructSettingPath(const Setting &setting, int idx) +{ + std::stringstream ss; + __writeSettingPath(setting, ss); + ss << ".[" << idx << ']'; + return ss.str(); } // --------------------------------------------------------------------------- -SettingException::SettingException(const Setting &setting, int idx) +static std::string __constructSettingPath(const Setting &setting, const char *name) { - std::stringstream sstr; - __constructPath(setting, sstr); - sstr << ".[" << idx << "]"; + std::stringstream ss; + __writeSettingPath(setting, ss); + ss << ".[" << name << ']'; + return ss.str(); +} - _path = ::strdup(sstr.str().c_str()); +// --------------------------------------------------------------------------- + +static std::string __constructErrorMessage(char const *derivedType, std::string const & path) +{ + std::stringstream ss; + ss << derivedType << ": " << path; + return ss.str(); } // --------------------------------------------------------------------------- -SettingException::SettingException(const Setting &setting, const char *name) +SettingException::SettingException(char const *derivedType, std::string path) + : ConfigException(__constructErrorMessage(derivedType, path)) + , _path(std::move(path)) { - std::stringstream sstr; - __constructPath(setting, sstr); - sstr << '.' << name; +} + +// --------------------------------------------------------------------------- - _path = ::strdup(sstr.str().c_str()); +SettingException::SettingException(char const *derivedType, + const Setting &setting) + : SettingException(derivedType, __constructSettingPath(setting)) +{ } // --------------------------------------------------------------------------- -SettingException::SettingException(const char *path) +SettingException::SettingException(char const *derivedType, + const Setting &setting, + int idx) + : SettingException(derivedType, __constructSettingPath(setting, idx)) { - _path = ::strdup(path); } // --------------------------------------------------------------------------- -const char *SettingException::getPath() const +SettingException::SettingException(char const *derivedType, + const Setting &setting, + const char *name) + : SettingException(derivedType, __constructSettingPath(setting, name)) { - return(_path); } // --------------------------------------------------------------------------- -SettingException::SettingException(const SettingException &other) - : ConfigException(other) +SettingException::SettingException(const Setting &setting) + : SettingException("setting exception", setting) { - _path = ::strdup(other._path); } // --------------------------------------------------------------------------- -SettingException &SettingException::operator=(const SettingException &other) +SettingException::SettingException(const Setting &setting, int idx) + : SettingException("setting exception", setting, idx) { - ::free(_path); - _path = ::strdup(other._path); +} - return(*this); +// --------------------------------------------------------------------------- + +SettingException::SettingException(const Setting &setting, const char *name) + : SettingException("setting exception", setting, name) +{ } // --------------------------------------------------------------------------- -const char *SettingException::what() const LIBCONFIGXX_NOEXCEPT +SettingException::SettingException(const char *path) + : SettingException("setting exception", path) { - return("SettingException"); } // --------------------------------------------------------------------------- -SettingException::~SettingException() LIBCONFIGXX_NOEXCEPT +std::string const & SettingException::getPath() const { - ::free(_path); + return(_path); } // --------------------------------------------------------------------------- -SettingTypeException::SettingTypeException(const Setting &setting) - : SettingException(setting) +SettingException::SettingException(const SettingException &other) + : ConfigException(other) + , _path(other._path) { } // --------------------------------------------------------------------------- -SettingTypeException::SettingTypeException(const Setting &setting, int idx) - : SettingException(setting, idx) +SettingException &SettingException::operator=(const SettingException &other) { + ConfigException::operator=(other); + _path = other._path; + + return(*this); } // --------------------------------------------------------------------------- -SettingTypeException::SettingTypeException(const Setting &setting, - const char *name) - : SettingException(setting, name) +SettingException::~SettingException() LIBCONFIGXX_NOEXCEPT { } // --------------------------------------------------------------------------- -const char *SettingTypeException::what() const LIBCONFIGXX_NOEXCEPT +SettingTypeException::SettingTypeException(const Setting &setting) + : SettingException("setting type exception", setting) { - return("SettingTypeException"); } // --------------------------------------------------------------------------- -SettingNotFoundException::SettingNotFoundException(const Setting &setting, - int idx) - : SettingException(setting, idx) +SettingTypeException::SettingTypeException(const Setting &setting, int idx) + : SettingException("setting type exception", setting, idx) { } // --------------------------------------------------------------------------- -SettingNotFoundException::SettingNotFoundException(const Setting &setting, - const char *name) - : SettingException(setting, name) +SettingTypeException::SettingTypeException(const Setting &setting, + const char *name) + : SettingException("setting type exception", setting, name) { } // --------------------------------------------------------------------------- -SettingNotFoundException::SettingNotFoundException(const char *path) - : SettingException(path) +SettingNotFoundException::SettingNotFoundException(const Setting &setting, + int idx) + : SettingException("setting not found exception", setting, idx) { } // --------------------------------------------------------------------------- -const char *SettingNotFoundException::what() const LIBCONFIGXX_NOEXCEPT +SettingNotFoundException::SettingNotFoundException(const Setting &setting, + const char *name) + : SettingException("setting not found exception", setting, name) { - return("SettingNotFoundException"); } // --------------------------------------------------------------------------- -SettingNameException::SettingNameException(const Setting &setting, - const char *name) - : SettingException(setting, name) +SettingNotFoundException::SettingNotFoundException(const char *path) + : SettingException("setting not found exception", path) { } // --------------------------------------------------------------------------- -const char *SettingNameException::what() const LIBCONFIGXX_NOEXCEPT +SettingNameException::SettingNameException(const Setting &setting, + const char *name) + : SettingException("setting name exception", setting, name) { - return("SettingNameException"); } // --------------------------------------------------------------------------- -const char *FileIOException::what() const LIBCONFIGXX_NOEXCEPT +FileIOException::FileIOException() + : ConfigException("file io exception") { - return("FileIOException"); } // --------------------------------------------------------------------------- @@ -1026,7 +1103,7 @@ std::string Setting::getPath() const { std::stringstream path; - __constructPath(*this, path); + __writeSettingPath(*this, path); return(path.str()); }