Use STL exceptions as far as possible.

This commit is contained in:
Gunnar Beutner 2012-05-26 21:30:04 +02:00
parent c38e9c8468
commit 33d67401b9
20 changed files with 79 additions and 121 deletions

View File

@ -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.");
}
}

View File

@ -24,8 +24,6 @@ namespace icinga {
class Component;
DEFINE_EXCEPTION_CLASS(ComponentLoadException);
/**
* Abstract base class for applications.
*

View File

@ -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;
}

View File

@ -73,7 +73,7 @@ public:
*value = dynamic_pointer_cast<Dictionary>(object);
if (!*value)
throw InvalidCastException();
throw runtime_error("Object is not a dictionary.");
return true;
}

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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."));
}
/**

View File

@ -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."));
}

View File

@ -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);

View File

@ -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<SSL_CTX> 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<X509>& 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;
}

View File

@ -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.");
}
/**

View File

@ -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());
}

View File

@ -363,7 +363,7 @@ bool DiscoveryComponent::HasMessagePermission(Dictionary::Ptr roles, string mess
Dictionary::Ptr permissions = dynamic_pointer_cast<Dictionary>(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<Dictionary>(object);
if (!roles)
throw InvalidCastException();
throw runtime_error("Object is not a dictionary.");
}
}

View File

@ -70,7 +70,7 @@ shared_ptr<SSL_CTX> 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<EndpointManager>(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<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
{

View File

@ -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)

View File

@ -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;
}

View File

@ -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<Dictionary>(object);
if (!dictionary)
throw InvalidCastException();
throw runtime_error("Object is not a dictionary.");
*value = MessagePart(dictionary);
return true;

View File

@ -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]);