]> granicus.if.org Git - icinga2/commitdiff
Improve error message for duplicate objects
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 9 Sep 2014 12:49:21 +0000 (14:49 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 9 Sep 2014 12:49:21 +0000 (14:49 +0200)
refs #6070

20 files changed:
lib/base/CMakeLists.txt
lib/base/application.cpp
lib/base/debuginfo.cpp [moved from lib/config/debuginfo.cpp with 93% similarity]
lib/base/debuginfo.hpp [moved from lib/config/debuginfo.hpp with 79% similarity]
lib/base/dynamicobject.cpp
lib/base/dynamicobject.hpp
lib/base/dynamictype.cpp
lib/base/exception.cpp
lib/base/exception.hpp
lib/config/CMakeLists.txt
lib/config/aexpression.hpp
lib/config/applyrule.hpp
lib/config/configcompiler.hpp
lib/config/configcompilercontext.hpp
lib/config/configerror.cpp
lib/config/configerror.hpp
lib/config/configitem.cpp
lib/config/configitembuilder.hpp
lib/config/objectrule.hpp
lib/config/typerule.hpp

index fa79a8dc1da1500db181934450f864223933353b..dedfb158798a1907da5b0f117fda6545d92f5135 100644 (file)
@@ -24,7 +24,7 @@ mkclass_target(sysloglogger.ti sysloglogger.thpp)
 
 set(base_SOURCES
   application.cpp application.thpp array.cpp context.cpp
-  convert.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
+  convert.cpp debuginfo.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
   exception.cpp fifo.cpp filelogger.cpp filelogger.thpp logger.cpp logger.thpp
   netstring.cpp networkstream.cpp object.cpp objectlock.cpp process.cpp
   qstring.cpp ringbuffer.cpp scriptfunction.cpp scriptfunctionwrapper.cpp
index 0264f73245ba855a05f57e882f3a8f72af6b283b..8d5365bc7d27b8face46eece05b5d83e1ba98860 100644 (file)
@@ -50,6 +50,7 @@ bool Application::m_RequestRestart = false;
 bool Application::m_RequestReopenLogs = false;
 pid_t Application::m_ReloadProcess = 0;
 static bool l_Restarting = false;
+static bool l_InExceptionHandler = false;
 int Application::m_ArgC;
 char **Application::m_ArgV;
 double Application::m_StartTime;
@@ -578,6 +579,12 @@ BOOL WINAPI Application::CtrlHandler(DWORD type)
  */
 void Application::ExceptionHandler(void)
 {
+       if (l_InExceptionHandler)
+               for (;;)
+                       Utility::Sleep(5);
+
+       l_InExceptionHandler = true;
+
 #ifndef _WIN32
        struct sigaction sa;
        memset(&sa, 0, sizeof(sa));
@@ -607,6 +614,11 @@ void Application::ExceptionHandler(void)
 #ifdef _WIN32
 LONG CALLBACK Application::SEHUnhandledExceptionFilter(PEXCEPTION_POINTERS exi)
 {
+       if (l_InExceptionHandler)
+               return EXCEPTION_CONTINUE_SEARCH;
+
+       l_InExceptionHandler = true;
+
        DisplayInfoMessage();
 
        std::cerr << "Caught unhandled SEH exception." << std::endl
similarity index 93%
rename from lib/config/debuginfo.cpp
rename to lib/base/debuginfo.cpp
index 1fbbe8ba7d56964385bc742cedf48e2d7a83a6c3..3b4cec312e0d60db0af573141321a47f03a608a6 100644 (file)
@@ -17,7 +17,7 @@
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
  ******************************************************************************/
 
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
 #include "base/convert.hpp"
 #include <fstream>
 
@@ -107,3 +107,12 @@ void icinga::ShowCodeFragment(std::ostream& out, const DebugInfo& di, bool verbo
                }
        }
 }
+
+std::string icinga::to_string(const errinfo_debuginfo& e)
+{
+       std::ostringstream msgbuf;
+       msgbuf << "Config location: " << e.value() << "\n";
+       ShowCodeFragment(msgbuf, e.value(), true);
+       return msgbuf.str();
+}
+
similarity index 79%
rename from lib/config/debuginfo.hpp
rename to lib/base/debuginfo.hpp
index 84c97e74d61702800e348ef4b54badb6175f2bc0..9162fb9687cffc058746e0c1340b4418427ad81a 100644 (file)
@@ -20,8 +20,9 @@
 #ifndef DEBUGINFO_H
 #define DEBUGINFO_H
 
-#include "config/i2-config.hpp"
+#include "base/i2-base.hpp"
 #include "base/qstring.hpp"
+#include "base/exception.hpp"
 
 namespace icinga
 {
@@ -60,11 +61,16 @@ struct DebugInfo
        };
 };
 
-I2_CONFIG_API std::ostream& operator<<(std::ostream& out, const DebugInfo& val);
+I2_BASE_API std::ostream& operator<<(std::ostream& out, const DebugInfo& val);
 
-I2_CONFIG_API DebugInfo DebugInfoRange(const DebugInfo& start, const DebugInfo& end);
+I2_BASE_API DebugInfo DebugInfoRange(const DebugInfo& start, const DebugInfo& end);
 
-I2_CONFIG_API void ShowCodeFragment(std::ostream& out, const DebugInfo& di, bool verbose);
+I2_BASE_API void ShowCodeFragment(std::ostream& out, const DebugInfo& di, bool verbose);
+
+struct errinfo_debuginfo_;
+typedef boost::error_info<struct errinfo_debuginfo_, DebugInfo> errinfo_debuginfo;
+
+std::string to_string(const errinfo_debuginfo& e);
 
 }
 
index c56e0c5a4bb0c9f83c3b27ac2cc8945487f96013..0d6ac66299e0dd1ff42a77a1b3683a7a6f361404 100644 (file)
@@ -54,6 +54,16 @@ DynamicType::Ptr DynamicObject::GetType(void) const
        return DynamicType::GetByName(GetTypeName());
 }
 
+DebugInfo DynamicObject::GetDebugInfo(void) const
+{
+       return m_DebugInfo;
+}
+
+void DynamicObject::SetDebugInfo(const DebugInfo& di)
+{
+       m_DebugInfo = di;
+}
+
 bool DynamicObject::IsActive(void) const
 {
        return GetActive();
index fabf34b9bed61bdc061f716e44201e78346f5935..1b64b0d2caca5d6bc55e600fa493985e096904f8 100644 (file)
@@ -25,6 +25,7 @@
 #include "base/object.hpp"
 #include "base/serializer.hpp"
 #include "base/dictionary.hpp"
+#include "base/debuginfo.hpp"
 #include <boost/signals2.hpp>
 #include <map>
 
@@ -53,6 +54,9 @@ public:
 
        shared_ptr<DynamicType> GetType(void) const;
 
+       DebugInfo GetDebugInfo(void) const;
+       void SetDebugInfo(const DebugInfo& di);
+
        bool IsActive(void) const;
        bool IsPaused(void) const;
 
@@ -93,6 +97,8 @@ protected:
 private:
        static DynamicObject::Ptr GetObject(const String& type, const String& name);
        static void RestoreObject(const String& message, int attributeTypes);
+
+       DebugInfo m_DebugInfo;
 };
 
 #define DECLARE_TYPENAME(klass)                                                \
index 219dfcc18998c5cb19e791d556c2d323ff9b991c..57a09639a904a7f0954e01b9c8796918651b94cb 100644 (file)
@@ -21,6 +21,7 @@
 #include "base/serializer.hpp"
 #include "base/debug.hpp"
 #include "base/objectlock.hpp"
+#include "base/convert.hpp"
 
 using namespace icinga;
 
@@ -99,7 +100,9 @@ void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
                        if (it->second == object)
                                return;
 
-                       BOOST_THROW_EXCEPTION(std::runtime_error("RegisterObject() found existing object with the same name: " + name));
+                       BOOST_THROW_EXCEPTION(user_error("An object with type '" + m_Name + "' and name '" + name + "' already exists (" +
+                           Convert::ToString(it->second->GetDebugInfo()) + "), new declaration: " + Convert::ToString(object->GetDebugInfo()))
+                           << errinfo_debuginfo(object->GetDebugInfo()));
                }
 
                m_ObjectMap[name] = object;
index a2a9c6a9be41a0559b5a3184d880be5c58e34cfc..f809dbe3d7cb2af8315a7aa30316cfb403bc8514 100644 (file)
@@ -153,3 +153,18 @@ String icinga::DiagnosticInformation(boost::exception_ptr eptr)
        return boost::diagnostic_information(eptr);
 }
 
+user_error::user_error(void)
+{ }
+
+user_error::user_error(const String& message)
+       : m_Message(message)
+{ }
+
+user_error::~user_error(void) throw()
+{ }
+
+const char *user_error::what(void) const throw()
+{
+       return m_Message.CStr();
+}
+
index dbbb1906ccc9dbae64aea6f3673a1f5b81225637..c47ce34d7229ae822bcf48ff4bfecb3e53010cc9 100644 (file)
 namespace icinga
 {
 
-class I2_BASE_API user_error : virtual public std::exception, virtual public boost::exception { };
+class I2_BASE_API user_error : virtual public std::exception, virtual public boost::exception {
+public:
+       user_error(void);
+       user_error(const String& message);
+       ~user_error(void) throw();
+
+       const char *what(void) const throw();
+
+private:
+       String m_Message;
+};
 
 I2_BASE_API StackTrace *GetLastExceptionStack(void);
 I2_BASE_API void SetLastExceptionStack(const StackTrace& trace);
index a442540619b73b2151df928eaf955d2b01db530c..db582cbe3804f049fea4f62467d201956bac301a 100644 (file)
@@ -34,7 +34,7 @@ set(config_SOURCES
   aexpression.cpp applyrule.cpp base-type.conf base-type.cpp
   configcompilercontext.cpp configcompiler.cpp configerror.cpp configitembuilder.cpp
   configitem.cpp ${FLEX_config_lexer_OUTPUTS} ${BISON_config_parser_OUTPUTS}
-  configtype.cpp debuginfo.cpp objectrule.cpp typerule.cpp typerulelist.cpp
+  configtype.cpp objectrule.cpp typerule.cpp typerulelist.cpp
 )
 
 if(ICINGA2_UNITY_BUILD)
index 8a416c4a7332392302b33588fd2d5312c36104ef..0e2f97c229d5a58dca78703d29282c40a3edaf33 100644 (file)
@@ -21,7 +21,7 @@
 #define AEXPRESSION_H
 
 #include "config/i2-config.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
 #include "base/array.hpp"
 #include "base/dictionary.hpp"
 
index b6fc6088c66302cb3e0e909346c56a2a792d2caf..147298c9ffb7317b0255509b37dad89e5eb7c27b 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "config/i2-config.hpp"
 #include "config/aexpression.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
 #include <boost/function.hpp>
 
 namespace icinga
index 69557b797384246d4829f667fa599e1c378bc343..3d1968bdb5cb13d69d425551c2df1c60ffbc4027 100644 (file)
@@ -21,7 +21,7 @@
 #define CONFIGCOMPILER_H
 
 #include "config/i2-config.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
 #include "base/registry.hpp"
 #include "base/initialize.hpp"
 #include "base/singleton.hpp"
index 22f611287ca32de334d1790aedaf8fe106dca458..2a3401e0cbdc296bb08f3dd2fec2e8eebf69d89a 100644 (file)
@@ -21,7 +21,7 @@
 #define CONFIGCOMPILERCONTEXT_H
 
 #include "config/i2-config.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
 #include <boost/thread/mutex.hpp>
 #include <vector>
 
index 845f359b63e8bd239bab7b8f35067918b85c0535..453cae65e78ae9c86bd83c7107135e22afb30305 100644 (file)
 using namespace icinga;
 
 ConfigError::ConfigError(const String& message)
-       : m_Message(message)
+       : user_error(message)
 { }
 
-ConfigError::~ConfigError(void) throw()
-{ }
-
-const char *ConfigError::what(void) const throw()
-{
-       return m_Message.CStr();
-}
-
-std::string icinga::to_string(const errinfo_debuginfo& e)
-{
-       std::ostringstream msgbuf;
-       msgbuf << "Config location: " << e.value() << "\n";
-       ShowCodeFragment(msgbuf, e.value(), true);
-       return msgbuf.str();
-}
index dc085c00dfeebf949177c12d4e9c2dbb198fcc9c..f389b9b11380ec6efb271a7053e0dcb87c02b702 100644 (file)
@@ -21,7 +21,7 @@
 #define CONFIGERROR_H
 
 #include "config/i2-config.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
 #include "base/exception.hpp"
 
 namespace icinga
@@ -34,19 +34,8 @@ class I2_CONFIG_API ConfigError : virtual public user_error
 {
 public:
        ConfigError(const String& message);
-       ~ConfigError(void) throw();
-
-       const char *what(void) const throw();
-
-private:
-       String m_Message;
 };
 
-struct errinfo_debuginfo_;
-typedef boost::error_info<struct errinfo_debuginfo_, DebugInfo> errinfo_debuginfo;
-
-std::string to_string(const errinfo_debuginfo& e);
-
 }
 
 #endif /* CONFIGERROR_H */
index 61bc1cb0a36754e208c15d5b8bf215d0ffbdce3b..6de092d4856b504141e033792e81348ebab529c8 100644 (file)
@@ -22,6 +22,7 @@
 #include "config/applyrule.hpp"
 #include "config/objectrule.hpp"
 #include "config/configtype.hpp"
+#include "config/configerror.hpp"
 #include "base/application.hpp"
 #include "base/dynamictype.hpp"
 #include "base/objectlock.hpp"
@@ -180,9 +181,6 @@ DynamicObject::Ptr ConfigItem::Commit(void)
        if (!dtype)
                BOOST_THROW_EXCEPTION(std::runtime_error("Type '" + GetType() + "' does not exist."));
 
-       if (dtype->GetObject(GetName()))
-           BOOST_THROW_EXCEPTION(std::runtime_error("An object with type '" + GetType() + "' and name '" + GetName() + "' already exists."));
-
        if (IsAbstract())
                return DynamicObject::Ptr();
 
@@ -195,6 +193,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
        }
 
        DynamicObject::Ptr dobj = dtype->CreateObject(properties);
+       dobj->SetDebugInfo(m_DebugInfo);
        dobj->Register();
 
        m_Object = dobj;
index 9c9a2a8428080af7570be7bd23393e18cbb00016..f53fb7b7c8fd32f93cd7738c755443eefbe9e207 100644 (file)
@@ -20,9 +20,9 @@
 #ifndef CONFIGITEMBUILDER_H
 #define CONFIGITEMBUILDER_H
 
-#include "config/debuginfo.hpp"
 #include "config/aexpression.hpp"
 #include "config/configitem.hpp"
+#include "base/debuginfo.hpp"
 #include "base/object.hpp"
 
 namespace icinga
index 6098fb60a40c17ddfd1dcddbcc55f44e30be5d67..f3ed2505c9e8b3594ccef741d14fc3b288479b9b 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "config/i2-config.hpp"
 #include "config/aexpression.hpp"
-#include "config/debuginfo.hpp"
+#include "base/debuginfo.hpp"
 #include "base/dynamictype.hpp"
 
 namespace icinga
index 8a1ab737e7db54ff0172b1cc102d71aaf309e2c9..2e6ece95a0abe834b3ac20b6e77d3c0e66e8b33c 100644 (file)
@@ -22,7 +22,7 @@
 \r
 #include "config/i2-config.hpp"\r
 #include "config/typerulelist.hpp"\r
-#include "config/debuginfo.hpp"\r
+#include "base/debuginfo.hpp"\r
 \r
 namespace icinga\r
 {\r