diff --git a/base/Makefile.am b/base/Makefile.am index c8f50b602..3113fbc85 100644 --- a/base/Makefile.am +++ b/base/Makefile.am @@ -17,6 +17,8 @@ libbase_la_SOURCES = \ configobject.h \ delegate.h \ event.h \ + exception.cpp \ + exception.h \ fifo.cpp \ fifo.h \ i2-base.h \ diff --git a/base/application.cpp b/base/application.cpp index 099fe0440..df4949ab0 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -196,7 +196,7 @@ Component::Ptr Application::LoadComponent(const string& path, const ConfigObject #endif /* _WIN32 */ if (hModule == NULL) - throw exception(/*"Could not load module"*/); + throw ComponentLoadException("Could not load module"); #ifdef _WIN32 pCreateComponent = (Component *(*)())GetProcAddress(hModule, "CreateComponent"); @@ -205,7 +205,7 @@ Component::Ptr Application::LoadComponent(const string& path, const ConfigObject #endif /* _WIN32 */ if (pCreateComponent == NULL) - throw exception(/*"Module does not contain CreateComponent function"*/); + throw ComponentLoadException("Loadable module does not contain CreateComponent function"); component = Component::Ptr(pCreateComponent()); component->SetApplication(static_pointer_cast(shared_from_this())); @@ -292,10 +292,7 @@ const string& Application::GetExeDirectory(void) PathEnv = getenv("PATH"); if (PathEnv != NULL) { - PathEnv = strdup(PathEnv); - - if (PathEnv == NULL) - throw exception(/*"strdup() failed"*/); + PathEnv = Memory::StrDup(PathEnv); FoundPath = false; diff --git a/base/application.h b/base/application.h index 99248cb88..a27afbb01 100644 --- a/base/application.h +++ b/base/application.h @@ -5,6 +5,8 @@ namespace icinga { class Component; +DEFINE_EXCEPTION_CLASS(ComponentLoadException); + class Application : public Object { private: bool m_ShuttingDown; @@ -56,7 +58,19 @@ int application_main(int argc, char **argv) Application::Instance->SetArguments(args); - result = Application::Instance->Main(args); +#ifndef _DEBUG + try { +#endif /* !_DEBUG */ + result = Application::Instance->Main(args); +#ifndef _DEBUG + } catch (const Exception& ex) { + cout << "---" << endl; + cout << "Exception: " << typeid(ex).name() << endl; + cout << "Message: " << ex.GetMessage() << endl; + + return EXIT_FAILURE; + } +#endif /* !_DEBUG */ Application::Instance.reset(); diff --git a/base/base.vcxproj b/base/base.vcxproj index 3802c4fa3..9b176e508 100644 --- a/base/base.vcxproj +++ b/base/base.vcxproj @@ -16,6 +16,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/base/exception.cpp b/base/exception.cpp new file mode 100644 index 000000000..f120c5f23 --- /dev/null +++ b/base/exception.cpp @@ -0,0 +1,21 @@ +#include "i2-base.h" + +using namespace icinga; + +Exception::Exception(void) +{ +} + +Exception::Exception(const string& message) +{ + m_Message = message; +} + +Exception::~Exception(void) +{ +} + +string Exception::GetMessage(void) const +{ + return m_Message; +} diff --git a/base/exception.h b/base/exception.h new file mode 100644 index 000000000..4853dde68 --- /dev/null +++ b/base/exception.h @@ -0,0 +1,42 @@ +#ifndef EXCEPTION_H +#define EXCEPTION_H + +namespace icinga +{ + +class Exception +{ +private: + string m_Message; + +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + Exception(void); + Exception(const string& message); + + virtual ~Exception(void); + + string GetMessage(void) const; +}; + +} + +#define DEFINE_EXCEPTION_CLASS(klass) \ + class klass : public Exception \ + { \ + public: \ + typedef shared_ptr Ptr; \ + typedef weak_ptr WeakPtr; \ + \ + inline klass(void) : Exception() \ + { \ + } \ + \ + inline klass(const string& message) : Exception(message) \ + { \ + } \ + }; + +#endif /* EXCEPTION_H */ diff --git a/base/i2-base.h b/base/i2-base.h index 47fae22e3..cfccd7b81 100644 --- a/base/i2-base.h +++ b/base/i2-base.h @@ -47,6 +47,7 @@ using namespace std::tr1::placeholders; #include "condvar.h" #include "thread.h" #include "object.h" +#include "exception.h" #include "memory.h" #include "delegate.h" #include "event.h" diff --git a/base/memory.cpp b/base/memory.cpp index 426825c31..d41d8a5a7 100644 --- a/base/memory.cpp +++ b/base/memory.cpp @@ -2,6 +2,10 @@ using namespace icinga; +Memory::Memory(void) +{ +} + void *Memory::Allocate(size_t size) { void *ptr = malloc(size); @@ -22,6 +26,16 @@ void *Memory::Reallocate(void *ptr, size_t size) return new_ptr; } +char *Memory::StrDup(const char *str) +{ + char *new_str = strdup(str); + + if (str == NULL) + throw OutOfMemoryException(); + + return new_str; +} + void Memory::Free(void *ptr) { if (ptr != NULL) diff --git a/base/memory.h b/base/memory.h index 1126c8089..9abd0d28c 100644 --- a/base/memory.h +++ b/base/memory.h @@ -4,16 +4,17 @@ namespace icinga { -class OutOfMemoryException : public exception { }; +DEFINE_EXCEPTION_CLASS(OutOfMemoryException); class Memory { private: - Memory(void) { } + Memory(void); public: static void *Allocate(size_t size); static void *Reallocate(void *ptr, size_t size); + static char *StrDup(const char *str); static void Free(void *ptr); }; diff --git a/base/object.h b/base/object.h index 8fa3f4826..00096adcd 100644 --- a/base/object.h +++ b/base/object.h @@ -44,6 +44,22 @@ shared_ptr new_object(void) return shared_ptr(instance); } +template +shared_ptr new_object(const TArg1& arg1) +{ + T *instance = new T(arg1); + + return shared_ptr(instance); +} + +template +shared_ptr new_object(const TArg1& arg1, const TArg2& arg2) +{ + T *instance = new T(arg1, arg2); + + return shared_ptr(instance); +} + typedef function factory_function; template diff --git a/configfilecomponent/configfilecomponent.cpp b/configfilecomponent/configfilecomponent.cpp index e99e8fdcc..688b88878 100644 --- a/configfilecomponent/configfilecomponent.cpp +++ b/configfilecomponent/configfilecomponent.cpp @@ -17,18 +17,20 @@ void ConfigFileComponent::Start(void) string filename; if (!GetConfig()->GetProperty("configFilename", &filename)) - throw exception(/*"Missing configFilename property"*/); + throw ConfigParserException("Missing configFilename property"); fp.open(filename.c_str(), ifstream::in); if (fp.fail()) - throw exception(/*"Could not open config file"*/); + throw ConfigParserException("Could not open config file"); + GetApplication()->Log("Reading config file: %s", filename.c_str()); + while (!fp.eof()) { size_t bufferSize = 1024; char *buffer = (char *)fifo->GetWriteBuffer(&bufferSize); fp.read(buffer, bufferSize); if (fp.bad()) - throw exception(/*"Could not read from config file"*/); + throw ConfigParserException("Could not read from config file"); fifo->Write(NULL, fp.gcount()); } @@ -41,7 +43,7 @@ void ConfigFileComponent::Start(void) fifo->Read(NULL, fifo->GetSize()); if (jsonobj == NULL) - throw exception(/*"Could not parse config file."*/); + throw ConfigParserException("Could not parse config file."); for (cJSON *typeobj = jsonobj->child; typeobj != NULL; typeobj = typeobj->next) { string type = typeobj->string; diff --git a/configfilecomponent/configfilecomponent.h b/configfilecomponent/configfilecomponent.h index d681b530f..8d195f6ab 100644 --- a/configfilecomponent/configfilecomponent.h +++ b/configfilecomponent/configfilecomponent.h @@ -4,6 +4,8 @@ namespace icinga { +DEFINE_EXCEPTION_CLASS(ConfigParserException); + class ConfigFileComponent : public Component { public: