From: Gunnar Beutner Date: Sat, 26 May 2012 19:30:04 +0000 (+0200) Subject: Use STL exceptions as far as possible. X-Git-Tag: v0.0.1~480 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=33d67401b94b4338a215f25c2560d414d39a4ca5;p=icinga2 Use STL exceptions as far as possible. --- diff --git a/base/application.cpp b/base/application.cpp index d1c4fd5d1..0a3210c95 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -230,7 +230,7 @@ Component::Ptr Application::LoadComponent(const string& path, #endif /* _WIN32 */ if (hModule == NULL) - throw ComponentLoadException("Could not load module"); + throw runtime_error("Could not load module"); #ifdef _WIN32 pCreateComponent = (CreateComponentFunction)GetProcAddress(hModule, @@ -245,8 +245,8 @@ Component::Ptr Application::LoadComponent(const string& path, #endif /* _WIN32 */ if (pCreateComponent == NULL) - throw ComponentLoadException("Loadable module does not " - "contain CreateComponent function"); + throw runtime_error("Loadable module does not contain " + "CreateComponent function"); component = Component::Ptr(pCreateComponent()); component->SetConfig(componentConfig); @@ -368,7 +368,7 @@ string Application::GetExeDirectory(void) const free(PathEnv); if (!FoundPath) - throw Exception("Could not determine executable path."); + throw runtime_error("Could not determine executable path."); } } diff --git a/base/application.h b/base/application.h index 5b22db9f6..c8ee5afd1 100644 --- a/base/application.h +++ b/base/application.h @@ -24,8 +24,6 @@ namespace icinga { class Component; -DEFINE_EXCEPTION_CLASS(ComponentLoadException); - /** * Abstract base class for applications. * diff --git a/base/configobject.cpp b/base/configobject.cpp index 65ac03941..d0a1ba49e 100644 --- a/base/configobject.cpp +++ b/base/configobject.cpp @@ -42,7 +42,7 @@ ConfigObject::ConfigObject(const string& type, const string& name) void ConfigObject::SetHive(const ConfigHive::WeakPtr& hive) { if (m_Hive.lock()) - throw InvalidArgumentException("Config object already has a parent hive."); + throw logic_error("Config object already has a parent hive."); m_Hive = hive; } diff --git a/base/dictionary.h b/base/dictionary.h index 5cf00ac9f..253b6fbe7 100644 --- a/base/dictionary.h +++ b/base/dictionary.h @@ -73,7 +73,7 @@ public: *value = dynamic_pointer_cast(object); if (!*value) - throw InvalidCastException(); + throw runtime_error("Object is not a dictionary."); return true; } diff --git a/base/exception.cpp b/base/exception.cpp index 5a6dcc95b..00858c1f2 100644 --- a/base/exception.cpp +++ b/base/exception.cpp @@ -21,35 +21,6 @@ using namespace icinga; -/** - * Default constructor for the Exception class. - */ -Exception::Exception(void) -{ - m_Code = 0; - m_Message = NULL; -} - -/** - * Constructor for the exception class. - * - * @param message A message describing the exception. - */ -Exception::Exception(const char *message) -{ - m_Code = 0; - m_Message = NULL; - SetMessage(message); -} - -/** - * Destructor for the Exception class. Must be virtual for RTTI to work. - */ -Exception::~Exception(void) throw() -{ - Memory::Free(m_Message); -} - /** * Retrieves the error code for the exception. * @@ -75,7 +46,7 @@ void Exception::SetCode(int code) * * @returns The description. */ -const char *Exception::GetMessage(void) const +string Exception::GetMessage(void) const { return m_Message; } @@ -87,7 +58,7 @@ const char *Exception::GetMessage(void) const */ const char *Exception::what(void) const throw() { - return GetMessage(); + return GetMessage().c_str(); } /** @@ -95,10 +66,9 @@ const char *Exception::what(void) const throw() * * @param message The description. */ -void Exception::SetMessage(const char *message) +void Exception::SetMessage(string message) { - Memory::Free(m_Message); - m_Message = Memory::StrDup(message); + m_Message = message; } #ifdef _WIN32 diff --git a/base/exception.h b/base/exception.h index 3ab702e64..d614eb7cb 100644 --- a/base/exception.h +++ b/base/exception.h @@ -31,21 +31,35 @@ namespace icinga class I2_BASE_API Exception : public virtual std::exception { public: - Exception(void); - Exception(const char *message); - virtual ~Exception(void) throw(); + Exception(void) + : m_Message(), m_Code(0) + { } + + Exception(string message) + : m_Message(message), m_Code(0) + { } + + Exception(string message, int code) + : m_Message(message), m_Code(code) + { } + + /** + * Destructor for the Exception class. Must be virtual for RTTI to work. + */ + virtual ~Exception(void) throw() + { } int GetCode(void) const; - const char *GetMessage(void) const; + string GetMessage(void) const; virtual const char *what(void) const throw(); protected: void SetCode(int code); - void SetMessage(const char *message); + void SetMessage(string message); private: - char *m_Message; + string m_Message; int m_Code; }; @@ -54,13 +68,11 @@ private: { \ public: \ inline klass(void) : Exception() \ - { \ - } \ + { } \ \ - inline klass(const char *message) \ + inline klass(string message) \ : Exception(message) \ - { \ - } \ + { } \ } /** @@ -71,22 +83,6 @@ private: */ DEFINE_EXCEPTION_CLASS(NotImplementedException); -/** - * An exception that is thrown when an argument to - * a function is invalid. - * - * @ingroup base - */ -DEFINE_EXCEPTION_CLASS(InvalidArgumentException); - -/** - * An exception that is thrown when a cast yields - * an invalid result. - * - * @ingroup base - */ -DEFINE_EXCEPTION_CLASS(InvalidCastException); - #ifdef _WIN32 /** * A Win32 error encapsulated in an exception. @@ -101,11 +97,8 @@ public: * @param errorCode A Win32 error code. */ inline Win32Exception(const string& message, int errorCode) - { - string msg = message + ": " + FormatErrorCode(errorCode); - SetMessage(msg.c_str()); - SetCode(errorCode); - } + : Exception(message + ": " + FormatErrorCode(errorCode), errorCode) + { } /** * Returns a string that describes the Win32 error. @@ -130,11 +123,8 @@ public: * @param errorCode A Posix (errno) error code. */ inline PosixException(const string& message, int errorCode) - { - string msg = message + ": " + FormatErrorCode(errorCode); - SetMessage(msg.c_str()); - SetCode(errorCode); - } + : Exception(message + ": " + FormatErrorCode(errorCode), errorCode) + { } /** * Returns a string that describes the Posix error. @@ -158,10 +148,8 @@ public: * @param errorCode An OpenSSL error code. */ inline OpenSSLException(const string& message, int errorCode) - { - string msg = message + ": " + FormatErrorCode(errorCode); - SetMessage(msg.c_str()); - } + : Exception(message + ": " + FormatErrorCode(errorCode), errorCode) + { } /** * Returns a string that describes the OpenSSL error. diff --git a/base/socket.cpp b/base/socket.cpp index a876b3dcb..dfe44994b 100644 --- a/base/socket.cpp +++ b/base/socket.cpp @@ -167,17 +167,17 @@ int Socket::GetLastSocketError(void) * Handles a socket error by calling the OnError event or throwing an exception * when there are no observers for the OnError event. * - * @param exception An exception. + * @param ex An exception. */ -void Socket::HandleSocketError(const Exception& exception) +void Socket::HandleSocketError(const exception& ex) { if (OnError.HasObservers()) { - SocketErrorEventArgs sea(exception); + SocketErrorEventArgs sea(ex); OnError(sea); Close(); } else { - throw exception; + throw ex; } } @@ -226,7 +226,8 @@ string Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len) char service[NI_MAXSERV]; if (getnameinfo(address, len, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV) < 0) - throw InvalidArgumentException(); /* TODO: throw proper exception */ + throw SocketException("getnameinfo() failed", + GetLastSocketError()); stringstream s; s << "[" << host << "]:" << service; diff --git a/base/socket.h b/base/socket.h index 1d56c23d7..75c70d1c1 100644 --- a/base/socket.h +++ b/base/socket.h @@ -29,10 +29,10 @@ namespace icinga { */ struct I2_BASE_API SocketErrorEventArgs : public EventArgs { - const Exception& Error; + const exception& Exception; - SocketErrorEventArgs(const Exception& exception) - : Error(exception) { } + SocketErrorEventArgs(const exception& ex) + : Exception(ex) { } }; /** @@ -78,7 +78,7 @@ protected: int GetError(void) const; static int GetLastSocketError(void); - void HandleSocketError(const Exception& exception); + void HandleSocketError(const exception& ex); virtual void CloseInternal(bool from_dtor); diff --git a/base/tcpclient.cpp b/base/tcpclient.cpp index 0045cff5a..0308e4844 100644 --- a/base/tcpclient.cpp +++ b/base/tcpclient.cpp @@ -110,7 +110,8 @@ void TcpClient::Connect(const string& node, const string& service) freeaddrinfo(result); if (fd == INVALID_SOCKET) - HandleSocketError(InvalidArgumentException()); + HandleSocketError(runtime_error( + "Could not create a suitable socket.")); } /** diff --git a/base/tcpsocket.cpp b/base/tcpsocket.cpp index 2cce586d1..d2932e9a6 100644 --- a/base/tcpsocket.cpp +++ b/base/tcpsocket.cpp @@ -116,5 +116,6 @@ void TcpSocket::Bind(string node, string service, int family) freeaddrinfo(result); if (fd == INVALID_SOCKET) - HandleSocketError(InvalidArgumentException()); + HandleSocketError(runtime_error( + "Could not create a suitable socket.")); } diff --git a/base/tlsclient.cpp b/base/tlsclient.cpp index a9e1ebc80..2669b4d26 100644 --- a/base/tlsclient.cpp +++ b/base/tlsclient.cpp @@ -80,7 +80,7 @@ void TlsClient::Start(void) throw OpenSSLException("SSL_new failed", ERR_get_error()); if (!GetClientCertificate()) - throw InvalidArgumentException("No X509 client certificate was specified."); + throw logic_error("No X509 client certificate was specified."); if (!m_SSLIndexInitialized) { m_SSLIndex = SSL_get_ex_new_index(0, (void *)"TlsClient", NULL, NULL, NULL); diff --git a/base/utility.cpp b/base/utility.cpp index a1f404d1f..fa89e7d75 100644 --- a/base/utility.cpp +++ b/base/utility.cpp @@ -34,7 +34,7 @@ void Utility::Daemonize(void) { pid = fork(); if (pid < 0) - throw PosixException("fork failed", errno); + throw PosixException("fork() failed", errno); if (pid) exit(0); @@ -42,7 +42,7 @@ void Utility::Daemonize(void) { fd = open("/dev/null", O_RDWR); if (fd < 0) - throw PosixException("open failed", errno); + throw PosixException("open() failed", errno); if (fd != 0) dup2(fd, 0); @@ -57,7 +57,7 @@ void Utility::Daemonize(void) { close(fd); if (setsid() < 0) - throw PosixException("setsid failed", errno); + throw PosixException("setsid() failed", errno); #endif } @@ -94,13 +94,13 @@ shared_ptr Utility::MakeSSLContext(string pubkey, string privkey, strin SSL_CTX_set_mode(sslContext.get(), SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); if (!SSL_CTX_use_certificate_chain_file(sslContext.get(), pubkey.c_str())) - throw InvalidArgumentException("Could not load public X509 key file."); + throw OpenSSLException("Could not load public X509 key file", ERR_get_error()); if (!SSL_CTX_use_PrivateKey_file(sslContext.get(), privkey.c_str(), SSL_FILETYPE_PEM)) - throw InvalidArgumentException("Could not load private X509 key file."); + throw OpenSSLException("Could not load private X509 key file", ERR_get_error()); if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.c_str(), NULL)) - throw InvalidArgumentException("Could not load public CA key file."); + throw OpenSSLException("Could not load public CA key file", ERR_get_error()); return sslContext; } @@ -118,7 +118,7 @@ string Utility::GetCertificateCN(const shared_ptr& certificate) int rc = X509_NAME_get_text_by_NID(X509_get_subject_name(certificate.get()), NID_commonName, buffer, sizeof(buffer)); if (rc == -1) - throw InvalidArgumentException("X509 certificate has no CN attribute."); + throw OpenSSLException("X509 certificate has no CN attribute", ERR_get_error()); return buffer; } diff --git a/base/variant.cpp b/base/variant.cpp index 3c906df27..914bfdb14 100644 --- a/base/variant.cpp +++ b/base/variant.cpp @@ -39,7 +39,7 @@ void Variant::Convert(VariantType newType) const } // TODO: convert variant data - throw InvalidArgumentException("Invalid variant conversion."); + throw runtime_error("Invalid variant conversion."); } /** diff --git a/components/configfile/configfilecomponent.cpp b/components/configfile/configfilecomponent.cpp index 08b52233e..d89b8c0be 100644 --- a/components/configfile/configfilecomponent.cpp +++ b/components/configfile/configfilecomponent.cpp @@ -36,11 +36,11 @@ void ConfigFileComponent::Start(void) string filename; if (!GetConfig()->GetProperty("configFilename", &filename)) - throw InvalidArgumentException("Missing 'configFilename' property"); + throw logic_error("Missing 'configFilename' property"); fp.open(filename.c_str(), ifstream::in); if (fp.fail()) - throw ConfigParserException("Could not open config file"); + throw runtime_error("Could not open config file"); GetIcingaApplication()->Log("Reading config file: " + filename); @@ -49,7 +49,7 @@ void ConfigFileComponent::Start(void) char *buffer = (char *)fifo->GetWriteBuffer(&bufferSize); fp.read(buffer, bufferSize); if (fp.bad()) - throw ConfigParserException("Could not read from config file"); + throw runtime_error("Could not read from config file"); fifo->Write(NULL, fp.gcount()); } diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp index 815f35557..9965353bf 100644 --- a/components/discovery/discoverycomponent.cpp +++ b/components/discovery/discoverycomponent.cpp @@ -363,7 +363,7 @@ bool DiscoveryComponent::HasMessagePermission(Dictionary::Ptr roles, string mess Dictionary::Ptr permissions = dynamic_pointer_cast(object); if (!permissions) - throw InvalidCastException(); + throw runtime_error("Object is not a dictionary."); for (DictionaryIterator is = permissions->Begin(); is != permissions->End(); is++) { if (Utility::Match(is->second.GetString(), message)) @@ -404,9 +404,8 @@ void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessa Object::Ptr object; if (endpointConfig->GetProperty("roles", &object)) { roles = dynamic_pointer_cast(object); - if (!roles) - throw InvalidCastException(); + throw runtime_error("Object is not a dictionary."); } } diff --git a/icinga/endpointmanager.cpp b/icinga/endpointmanager.cpp index 2b59db4f4..728285b11 100644 --- a/icinga/endpointmanager.cpp +++ b/icinga/endpointmanager.cpp @@ -70,7 +70,7 @@ shared_ptr EndpointManager::GetSSLContext(void) const void EndpointManager::AddListener(string service) { if (!GetSSLContext()) - throw InvalidArgumentException("SSL context is required for AddListener()"); + throw logic_error("SSL context is required for AddListener()"); stringstream s; s << "Adding new listener: port " << service; @@ -151,7 +151,7 @@ void EndpointManager::UnregisterServer(JsonRpcServer::Ptr server) void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint) { if (!endpoint->IsLocal() && endpoint->GetIdentity() != "") - throw InvalidArgumentException("Identity must be empty."); + throw invalid_argument("Identity must be empty."); endpoint->SetEndpointManager(static_pointer_cast(shared_from_this())); m_Endpoints.push_back(endpoint); @@ -220,11 +220,11 @@ void EndpointManager::SendMulticastMessage(Endpoint::Ptr sender, { string id; if (message.GetID(&id)) - throw InvalidArgumentException("Multicast requests must not have an ID."); + throw invalid_argument("Multicast requests must not have an ID."); string method; if (!message.GetMethod(&method)) - throw InvalidArgumentException("Message is missing the 'method' property."); + throw invalid_argument("Message is missing the 'method' property."); for (vector::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) { diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index 6cb33299c..002125a7a 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -168,7 +168,7 @@ int IcingaApplication::NewIcingaConfigHandler(const EventArgs& ea) int IcingaApplication::DeletedIcingaConfigHandler(const EventArgs&) { - throw Exception("Unsupported operation."); + throw runtime_error("Unsupported operation."); } void IcingaApplication::SetPrivateKeyFile(string privkey) diff --git a/icinga/jsonrpcendpoint.cpp b/icinga/jsonrpcendpoint.cpp index 81ce236c0..6386269c0 100644 --- a/icinga/jsonrpcendpoint.cpp +++ b/icinga/jsonrpcendpoint.cpp @@ -132,7 +132,7 @@ int JsonRpcEndpoint::ClientClosedHandler(const EventArgs&) int JsonRpcEndpoint::ClientErrorHandler(const SocketErrorEventArgs& ea) { - cerr << "Error occured for JSON-RPC socket: Code=" << ea.Error.GetCode() << "; Message=" << ea.Error.GetMessage() << endl; + cerr << "Error occured for JSON-RPC socket: Message=" << ea.Exception.what() << endl; return 0; } diff --git a/jsonrpc/messagepart.cpp b/jsonrpc/messagepart.cpp index fa6bafb01..72e8d2765 100644 --- a/jsonrpc/messagepart.cpp +++ b/jsonrpc/messagepart.cpp @@ -41,7 +41,7 @@ MessagePart::MessagePart(string jsonString) json_t *json = cJSON_Parse(jsonString.c_str()); if (!json) - throw InvalidArgumentException("Invalid JSON string"); + throw runtime_error("Invalid JSON string"); m_Dictionary = GetDictionaryFromJson(json); @@ -184,7 +184,7 @@ bool MessagePart::GetProperty(string key, MessagePart *value) const Dictionary::Ptr dictionary = dynamic_pointer_cast(object); if (!dictionary) - throw InvalidCastException(); + throw runtime_error("Object is not a dictionary."); *value = MessagePart(dictionary); return true; diff --git a/jsonrpc/netstring.cpp b/jsonrpc/netstring.cpp index 10ab6686f..57b705640 100644 --- a/jsonrpc/netstring.cpp +++ b/jsonrpc/netstring.cpp @@ -41,7 +41,7 @@ bool Netstring::ReadStringFromFIFO(FIFO::Ptr fifo, string *str) /* no leading zeros allowed */ if (buffer[0] == '0' && isdigit(buffer[1])) - throw InvalidArgumentException("Invalid netstring (leading zero)"); + throw invalid_argument("Invalid netstring (leading zero)"); size_t len, i; @@ -49,7 +49,7 @@ bool Netstring::ReadStringFromFIFO(FIFO::Ptr fifo, string *str) for (i = 0; i < buffer_length && isdigit(buffer[i]); i++) { /* length specifier must have at most 9 characters */ if (i >= 9) - throw InvalidArgumentException("Length specifier must not exceed 9 characters"); + throw invalid_argument("Length specifier must not exceed 9 characters"); len = len * 10 + (buffer[i] - '0'); } @@ -60,11 +60,11 @@ bool Netstring::ReadStringFromFIFO(FIFO::Ptr fifo, string *str) /* check for the colon delimiter */ if (buffer[i++] != ':') - throw InvalidArgumentException("Invalid Netstring (missing :)"); + throw invalid_argument("Invalid Netstring (missing :)"); /* check for the comma delimiter after the string */ if (buffer[i + len] != ',') - throw InvalidArgumentException("Invalid Netstring (missing ,)"); + throw invalid_argument("Invalid Netstring (missing ,)"); *str = string(&buffer[i], &buffer[i + len]);