Cleaned up socket exception handling.

This commit is contained in:
Gunnar Beutner 2012-07-17 20:41:06 +02:00
parent a224c20a30
commit 0ad6026f29
40 changed files with 179 additions and 199 deletions

View File

@ -39,7 +39,7 @@ Application::Application(void)
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
throw Win32Exception("WSAStartup failed", WSAGetLastError());
throw_exception(Win32Exception("WSAStartup failed", WSAGetLastError()));
#else /* _WIN32 */
lt_dlinit();
#endif /* _WIN32 */
@ -133,12 +133,12 @@ Component::Ptr Application::LoadComponent(const string& path,
HMODULE hModule = LoadLibrary(path.c_str());
if (hModule == NULL)
throw Win32Exception("LoadLibrary('" + path + "') failed", GetLastError());
throw_exception(Win32Exception("LoadLibrary('" + path + "') failed", GetLastError()));
#else /* _WIN32 */
lt_dlhandle hModule = lt_dlopen(path.c_str());
if (hModule == NULL) {
throw runtime_error("Could not load module '" + path + "': " + lt_dlerror());
throw_exception(runtime_error("Could not load module '" + path + "': " + lt_dlerror()));
}
#endif /* _WIN32 */
@ -155,8 +155,8 @@ Component::Ptr Application::LoadComponent(const string& path,
#endif /* _WIN32 */
if (pCreateComponent == NULL)
throw runtime_error("Loadable module does not contain "
"CreateComponent function");
throw_exception(runtime_error("Loadable module does not contain "
"CreateComponent function"));
component = Component::Ptr(pCreateComponent());
component->SetConfig(componentConfig);
@ -228,7 +228,7 @@ string Application::GetExePath(void) const
char buffer[MAXPATHLEN];
if (getcwd(buffer, sizeof(buffer)) == NULL)
throw PosixException("getcwd failed", errno);
throw_exception(PosixException("getcwd failed", errno));
string workingDirectory = buffer;
if (argv0[0] != '/')
@ -255,20 +255,20 @@ string Application::GetExePath(void) const
if (!foundPath) {
executablePath.clear();
throw runtime_error("Could not determine executable path.");
throw_exception(runtime_error("Could not determine executable path."));
}
}
}
if (realpath(executablePath.c_str(), buffer) == NULL)
throw PosixException("realpath failed", errno);
throw_exception(PosixException("realpath failed", errno));
result = buffer;
#else /* _WIN32 */
char FullExePath[MAXPATHLEN];
if (!GetModuleFileName(NULL, FullExePath, sizeof(FullExePath)))
throw Win32Exception("GetModuleFileName() failed", GetLastError());
throw_exception(Win32Exception("GetModuleFileName() failed", GetLastError()));
result = FullExePath;
#endif /* _WIN32 */
@ -410,15 +410,15 @@ void Application::UpdatePidFile(const string& filename)
m_PidFile = fopen(filename.c_str(), "w");
if (m_PidFile == NULL)
throw runtime_error("Could not open PID file '" + filename + "'");
throw_exception(runtime_error("Could not open PID file '" + filename + "'"));
#ifndef _WIN32
if (flock(fileno(m_PidFile), LOCK_EX | LOCK_NB) < 0) {
ClosePidFile();
throw runtime_error("Another instance of the application is "
throw_exception(runtime_error("Another instance of the application is "
"already running. Remove the '" + filename + "' file if "
"you're certain that this is not the case.");
"you're certain that this is not the case."));
}
#endif /* _WIN32 */

View File

@ -83,13 +83,13 @@ public:
TResult GetResult(void)
{
if (!m_Finished)
throw runtime_error("GetResult called on an unfinished AsyncTask");
throw_exception(runtime_error("GetResult called on an unfinished AsyncTask"));
if (m_ResultRetrieved)
throw runtime_error("GetResult called on an AsyncTask whose result was already retrieved.");
throw_exception(runtime_error("GetResult called on an AsyncTask whose result was already retrieved."));
if (m_Exception)
boost::rethrow_exception(m_Exception);
rethrow_exception(m_Exception);
m_ResultRetrieved = true;

View File

@ -208,7 +208,7 @@ ScriptTask::Ptr ConfigObject::InvokeMethod(const string& method,
ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName);
if (!func)
throw invalid_argument("Function '" + funcName + "' does not exist.");
throw_exception(invalid_argument("Function '" + funcName + "' does not exist."));
ScriptTask::Ptr task = boost::make_shared<ScriptTask>(func, arguments);
task->Start(callback);

View File

@ -57,7 +57,7 @@ void FIFO::ResizeBuffer(size_t newSize)
char *newBuffer = (char *)realloc(m_Buffer, newSize);
if (newBuffer == NULL)
throw bad_alloc();
throw_exception(bad_alloc());
m_Buffer = newBuffer;

View File

@ -104,6 +104,7 @@ using std::ostream;
using std::ofstream;
using std::exception;
using std::bad_alloc;
using std::bad_cast;
using std::runtime_error;
using std::logic_error;
@ -137,6 +138,9 @@ using boost::mutex;
using boost::condition_variable;
using boost::system_time;
using boost::tie;
using boost::throw_exception;
using boost::rethrow_exception;
using boost::current_exception;
namespace tuples = boost::tuples;

View File

@ -111,7 +111,7 @@ string Logger::SeverityToString(LogSeverity severity)
case LogCritical:
return "critical";
default:
throw invalid_argument("Invalid severity.");
throw_exception(invalid_argument("Invalid severity."));
}
}
@ -126,5 +126,5 @@ LogSeverity Logger::StringToSeverity(const string& severity)
else if (severity == "critical")
return LogCritical;
else
throw invalid_argument("Invalid severity: " + severity);
throw_exception(invalid_argument("Invalid severity: " + severity));
}

View File

@ -150,7 +150,7 @@ void Process::InitTask(void)
#endif /* _MSC_VER */
if (m_FP == NULL)
throw runtime_error("Could not create process.");
throw_exception(runtime_error("Could not create process."));
}
bool Process::RunTask(void)

View File

@ -62,10 +62,10 @@ void Socket::SetFD(SOCKET fd)
int flags;
flags = fcntl(fd, F_GETFL, 0);
if (flags < 0)
throw PosixException("fcntl failed", errno);
throw_exception(PosixException("fcntl failed", errno));
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
throw PosixException("fcntl failed", errno);
throw_exception(PosixException("fcntl failed", errno));
#else /* F_GETFL */
unsigned long lTrue = 1;
ioctlsocket(fd, FIONBIO, &lTrue);
@ -105,6 +105,8 @@ void Socket::CloseInternal(bool from_dtor)
if (m_FD == INVALID_SOCKET)
return;
SetConnected(false);
closesocket(m_FD);
m_FD = INVALID_SOCKET;
@ -146,30 +148,12 @@ int Socket::GetLastSocketError(void)
#endif /* _WIN32 */
}
/**
* Handles a socket error by calling the OnError event or throwing an exception
* when there are no observers for the OnError event.
*
* @param ex An exception.
*/
void Socket::HandleSocketError(const exception& ex)
{
if (!OnError.empty()) {
Event::Post(boost::bind(boost::ref(OnError), GetSelf(), runtime_error(ex.what())));
CloseInternal(false);
} else {
throw ex;
}
}
/**
* Processes errors that have occured for the socket.
*/
void Socket::HandleException(void)
{
HandleSocketError(SocketException(
"select() returned fd in except fdset", GetError()));
throw_exception(SocketException("select() returned fd in except fdset", GetError()));
}
/**
@ -208,9 +192,10 @@ string Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len)
char host[NI_MAXHOST];
char service[NI_MAXSERV];
if (getnameinfo(address, len, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV) < 0)
throw SocketException("getnameinfo() failed",
GetLastSocketError());
if (getnameinfo(address, len, host, sizeof(host), service,
sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV) < 0)
throw_exception(SocketException("getnameinfo() failed",
GetLastSocketError()));
stringstream s;
s << "[" << host << "]:" << service;
@ -229,12 +214,8 @@ string Socket::GetClientAddress(void)
sockaddr_storage sin;
socklen_t len = sizeof(sin);
if (getsockname(GetFD(), (sockaddr *)&sin, &len) < 0) {
HandleSocketError(SocketException(
"getsockname() failed", GetError()));
return string();
}
if (getsockname(GetFD(), (sockaddr *)&sin, &len) < 0)
throw_exception(SocketException("getsockname() failed", GetError()));
return GetAddressFromSockaddr((sockaddr *)&sin, len);
}
@ -251,12 +232,8 @@ string Socket::GetPeerAddress(void)
sockaddr_storage sin;
socklen_t len = sizeof(sin);
if (getpeername(GetFD(), (sockaddr *)&sin, &len) < 0) {
HandleSocketError(SocketException(
"getpeername() failed", GetError()));
return string();
}
if (getpeername(GetFD(), (sockaddr *)&sin, &len) < 0)
throw_exception(SocketException("getpeername() failed", GetError()));
return GetAddressFromSockaddr((sockaddr *)&sin, len);
}
@ -311,17 +288,23 @@ void Socket::ReadThreadProc(void)
if (GetFD() == INVALID_SOCKET)
return;
if (rc < 0) {
HandleSocketError(SocketException("select() failed", GetError()));
return;
try {
if (rc < 0)
throw_exception(SocketException("select() failed", GetError()));
if (FD_ISSET(fd, &readfds))
HandleReadable();
if (FD_ISSET(fd, &exceptfds))
HandleException();
} catch (const exception&) {
m_Exception = boost::current_exception();
CloseInternal(false);
break;
}
if (FD_ISSET(fd, &readfds))
HandleReadable();
if (FD_ISSET(fd, &exceptfds))
HandleException();
if (WantsToWrite())
m_WriteCV.notify_all(); /* notify Write thread */
}
@ -359,13 +342,19 @@ void Socket::WriteThreadProc(void)
if (GetFD() == INVALID_SOCKET)
return;
if (rc < 0) {
HandleSocketError(SocketException("select() failed", GetError()));
return;
}
try {
if (rc < 0)
throw_exception(SocketException("select() failed", GetError()));
if (FD_ISSET(fd, &writefds))
HandleWritable();
if (FD_ISSET(fd, &writefds))
HandleWritable();
} catch (const exception&) {
m_Exception = boost::current_exception();
CloseInternal(false);
break;
}
}
}
@ -383,3 +372,9 @@ bool Socket::IsConnected(void) const
{
return m_Connected;
}
void Socket::CheckException(void)
{
if (m_Exception)
rethrow_exception(m_Exception);
}

View File

@ -35,7 +35,6 @@ public:
~Socket(void);
boost::signal<void (const Socket::Ptr&, const exception&)> OnError;
boost::signal<void (const Socket::Ptr&)> OnClosed;
virtual void Start(void);
@ -47,6 +46,10 @@ public:
mutex& GetMutex(void) const;
bool IsConnected(void) const;
void CheckException(void);
protected:
Socket(void);
@ -54,11 +57,9 @@ protected:
SOCKET GetFD(void) const;
void SetConnected(bool connected);
bool IsConnected(void) const;
int GetError(void) const;
static int GetLastSocketError(void);
void HandleSocketError(const exception& ex);
virtual bool WantsToRead(void) const;
virtual bool WantsToWrite(void) const;
@ -69,8 +70,6 @@ protected:
virtual void CloseInternal(bool from_dtor);
mutable mutex m_Mutex;
private:
SOCKET m_FD; /**< The socket descriptor. */
bool m_Connected;
@ -80,6 +79,9 @@ private:
condition_variable m_WriteCV;
mutable mutex m_Mutex;
boost::exception_ptr m_Exception;
void ReadThreadProc(void);
void WriteThreadProc(void);

View File

@ -38,7 +38,7 @@ void StreamLogger::OpenFile(const string& filename)
stream->open(filename.c_str(), ofstream::out | ofstream::trunc);
if (!stream->good())
throw runtime_error("Could not open logfile '" + filename + "'");
throw_exception(runtime_error("Could not open logfile '" + filename + "'"));
} catch (const exception&) {
delete stream;
throw;

View File

@ -61,11 +61,8 @@ void TcpClient::Connect(const string& node, const string& service)
int rc = getaddrinfo(node.c_str(), service.c_str(), &hints, &result);
if (rc < 0) {
HandleSocketError(SocketException(
"getaddrinfo() failed", GetLastSocketError()));
return;
}
if (rc < 0)
throw_exception(SocketException("getaddrinfo() failed", GetLastSocketError()));
int fd = INVALID_SOCKET;
@ -96,8 +93,7 @@ void TcpClient::Connect(const string& node, const string& service)
freeaddrinfo(result);
if (fd == INVALID_SOCKET)
HandleSocketError(runtime_error(
"Could not create a suitable socket."));
throw_exception(runtime_error("Could not create a suitable socket."));
}
void TcpClient::HandleWritable(void)
@ -122,8 +118,7 @@ void TcpClient::HandleWritable(void)
if (rc <= 0) {
SetConnected(false);
HandleSocketError(SocketException("send() failed", GetError()));
return;
throw_exception(SocketException("send() failed", GetError()));
}
SetConnected(true);
@ -188,8 +183,7 @@ void TcpClient::HandleReadable(void)
if (rc <= 0) {
SetConnected(false);
HandleSocketError(SocketException("recv() failed", GetError()));
return;
throw_exception(SocketException("recv() failed", GetError()));
}
SetConnected(true);

View File

@ -54,11 +54,8 @@ function<TcpClient::Ptr(SOCKET)> TcpServer::GetFactoryFunction(void) const
*/
void TcpServer::Listen(void)
{
if (listen(GetFD(), SOMAXCONN) < 0) {
HandleSocketError(SocketException(
"listen() failed", GetError()));
return;
}
if (listen(GetFD(), SOMAXCONN) < 0)
throw_exception(SocketException("listen() failed", GetError()));
}
/**
@ -83,11 +80,8 @@ void TcpServer::HandleReadable(void)
fd = accept(GetFD(), (sockaddr *)&addr, &addrlen);
if (fd < 0) {
HandleSocketError(SocketException(
"accept() failed", GetError()));
return;
}
if (fd < 0)
throw_exception(SocketException("accept() failed", GetError()));
TcpClient::Ptr client = m_ClientFactory(fd);

View File

@ -32,12 +32,8 @@ void TcpSocket::MakeSocket(int family)
int fd = socket(family, SOCK_STREAM, 0);
if (fd == INVALID_SOCKET) {
HandleSocketError(SocketException(
"socket() failed", GetLastSocketError()));
return;
}
if (fd == INVALID_SOCKET)
throw_exception(SocketException("socket() failed", GetLastSocketError()));
SetFD(fd);
}
@ -72,12 +68,8 @@ void TcpSocket::Bind(string node, string service, int family)
hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(node.empty() ? NULL : node.c_str(),
service.c_str(), &hints, &result) < 0) {
HandleSocketError(SocketException(
"getaddrinfo() failed", GetLastSocketError()));
return;
}
service.c_str(), &hints, &result) < 0)
throw_exception(SocketException("getaddrinfo() failed", GetLastSocketError()));
int fd = INVALID_SOCKET;
@ -116,6 +108,5 @@ void TcpSocket::Bind(string node, string service, int family)
freeaddrinfo(result);
if (fd == INVALID_SOCKET)
HandleSocketError(runtime_error(
"Could not create a suitable socket."));
throw_exception(runtime_error("Could not create a suitable socket."));
}

View File

@ -113,11 +113,8 @@ void Timer::Call(void)
*
* @param interval The new interval.
*/
void Timer::SetInterval(long interval)
void Timer::SetInterval(unsigned long interval)
{
if (interval <= 0)
throw invalid_argument("interval");
m_Interval = interval;
}
@ -126,7 +123,7 @@ void Timer::SetInterval(long interval)
*
* @returns The interval.
*/
long Timer::GetInterval(void) const
unsigned long Timer::GetInterval(void) const
{
return m_Interval;
}

View File

@ -39,8 +39,8 @@ public:
Timer(void);
void SetInterval(long interval);
long GetInterval(void) const;
void SetInterval(unsigned long interval);
unsigned long GetInterval(void) const;
static long ProcessTimers(void);
@ -52,7 +52,7 @@ public:
boost::signal<void(const Timer::Ptr&)> OnTimerExpired;
private:
long m_Interval; /**< The interval of the timer. */
unsigned long m_Interval; /**< The interval of the timer. */
time_t m_Next; /**< When the next event should happen. */
static Timer::CollectionType m_Timers;

View File

@ -42,10 +42,10 @@ void TlsClient::Start(void)
m_SSL = shared_ptr<SSL>(SSL_new(m_SSLContext.get()), SSL_free);
if (!m_SSL)
throw OpenSSLException("SSL_new failed", ERR_get_error());
throw_exception(OpenSSLException("SSL_new failed", ERR_get_error()));
if (!GetClientCertificate())
throw logic_error("No X509 client certificate was specified.");
throw_exception(logic_error("No X509 client certificate was specified."));
if (!m_SSLIndexInitialized) {
m_SSLIndex = SSL_get_ex_new_index(0, (void *)"TlsClient", NULL, NULL, NULL);
@ -137,9 +137,7 @@ void TlsClient::HandleReadable(void)
CloseInternal(false);
goto post_event;
default:
HandleSocketError(OpenSSLException(
"SSL_read failed", ERR_get_error()));
goto post_event;
throw_exception(OpenSSLException("SSL_read failed", ERR_get_error()));
}
}
@ -194,9 +192,7 @@ void TlsClient::HandleWritable(void)
CloseInternal(false);
return;
default:
HandleSocketError(OpenSSLException(
"SSL_write failed", ERR_get_error()));
return;
throw_exception(OpenSSLException("SSL_write failed", ERR_get_error()));
}
}

View File

@ -58,7 +58,7 @@ void Utility::Daemonize(void) {
pid = fork();
if (pid < 0)
throw PosixException("fork() failed", errno);
throw_exception PosixException("fork() failed", errno);
if (pid)
exit(0);
@ -66,7 +66,7 @@ void Utility::Daemonize(void) {
fd = open("/dev/null", O_RDWR);
if (fd < 0)
throw PosixException("open() failed", errno);
throw_exception PosixException("open() failed", errno);
if (fd != STDIN_FILENO)
dup2(fd, STDIN_FILENO);
@ -81,7 +81,7 @@ void Utility::Daemonize(void) {
close(fd);
if (setsid() < 0)
throw PosixException("setsid() failed", errno);
throw_exception PosixException("setsid() failed", errno);
#endif
}
@ -116,19 +116,19 @@ 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 OpenSSLException("Could not load public X509 key file", ERR_get_error());
throw_exception(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 OpenSSLException("Could not load private X509 key file", ERR_get_error());
throw_exception(OpenSSLException("Could not load private X509 key file", ERR_get_error()));
if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.c_str(), NULL))
throw OpenSSLException("Could not load public CA key file", ERR_get_error());
throw_exception(OpenSSLException("Could not load public CA key file", ERR_get_error()));
STACK_OF(X509_NAME) *cert_names;
cert_names = SSL_load_client_CA_file(cakey.c_str());
if (cert_names == NULL)
throw OpenSSLException("SSL_load_client_CA_file() failed", ERR_get_error());
throw_exception(OpenSSLException("SSL_load_client_CA_file() failed", ERR_get_error()));
SSL_CTX_set_client_CA_list(sslContext.get(), cert_names);
@ -148,7 +148,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 OpenSSLException("X509 certificate has no CN attribute", ERR_get_error());
throw_exception(OpenSSLException("X509 certificate has no CN attribute", ERR_get_error()));
return buffer;
}
@ -165,14 +165,14 @@ shared_ptr<X509> Utility::GetX509Certificate(string pemfile)
BIO *fpcert = BIO_new(BIO_s_file());
if (fpcert == NULL)
throw OpenSSLException("BIO_new failed", ERR_get_error());
throw_exception(OpenSSLException("BIO_new failed", ERR_get_error()));
if (BIO_read_filename(fpcert, pemfile.c_str()) < 0)
throw OpenSSLException("BIO_read_filename failed", ERR_get_error());
throw_exception(OpenSSLException("BIO_read_filename failed", ERR_get_error()));
cert = PEM_read_bio_X509_AUX(fpcert, NULL, NULL, NULL);
if (cert == NULL)
throw OpenSSLException("PEM_read_bio_X509_AUX failed", ERR_get_error());
throw_exception(OpenSSLException("PEM_read_bio_X509_AUX failed", ERR_get_error()));
BIO_free(fpcert);
@ -203,14 +203,14 @@ string Utility::DirName(const string& path)
string result;
if (dir == NULL)
throw std::bad_alloc();
throw_exception(bad_alloc());
#ifndef _WIN32
result = dirname(dir);
#else /* _WIN32 */
if (!PathRemoveFileSpec(dir)) {
free(dir);
throw Win32Exception("PathRemoveFileSpec() failed", GetLastError());
throw_exception(Win32Exception("PathRemoveFileSpec() failed", GetLastError()));
}
result = dir;
@ -233,7 +233,7 @@ string Utility::BaseName(const string& path)
string result;
if (dir == NULL)
throw std::bad_alloc();
throw_exception(bad_alloc());
#ifndef _WIN32
result = basename(dir);

View File

@ -65,7 +65,7 @@ public:
Object::Ptr object = dynamic_pointer_cast<Object>(value);
if (!object)
throw invalid_argument("shared_ptr value type must inherit from Object class.");
throw_exception(invalid_argument("shared_ptr value type must inherit from Object class."));
m_Value = object;
}
@ -110,7 +110,7 @@ public:
shared_ptr<T> object = dynamic_pointer_cast<T>(boost::get<Object::Ptr>(m_Value));
if (!object)
throw bad_cast();
throw_exception(bad_cast());
return object;
}

View File

@ -48,7 +48,7 @@ Host Host::GetByName(const string& name)
ConfigObject::Ptr configObject = ConfigObject::GetObject("host", name);
if (!configObject)
throw invalid_argument("Host '" + name + "' does not exist.");
throw_exception(invalid_argument("Host '" + name + "' does not exist."));
return Host(configObject);
}

View File

@ -61,7 +61,7 @@ HostGroup HostGroup::GetByName(const string& name)
ConfigObject::Ptr configObject = ConfigObject::GetObject("hostgroup", name);
if (!configObject)
throw invalid_argument("HostGroup '" + name + "' does not exist.");
throw_exception(invalid_argument("HostGroup '" + name + "' does not exist."));
return HostGroup(configObject);
}

View File

@ -32,7 +32,7 @@ string MacroProcessor::ResolveMacros(const string& str, const vector<Dictionary:
pos_second = result.find_first_of('$', pos_first + 1);
if (pos_second == string::npos)
throw runtime_error("Closing $ not found in macro format string.");
throw_exception(runtime_error("Closing $ not found in macro format string."));
string name = result.substr(pos_first + 1, pos_second - pos_first - 1);
string value;
@ -46,7 +46,7 @@ string MacroProcessor::ResolveMacros(const string& str, const vector<Dictionary:
}
if (!resolved)
throw runtime_error("Macro '" + name + "' is not defined.");
throw_exception(runtime_error("Macro '" + name + "' is not defined."));
result.replace(pos_first, pos_second - pos_first + 1, value);

View File

@ -28,11 +28,11 @@ NagiosCheckTask::NagiosCheckTask(const ScriptTask::Ptr& task, const Process::Ptr
void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments)
{
if (arguments.size() < 1)
throw invalid_argument("Missing argument: Service must be specified.");
throw_exception(invalid_argument("Missing argument: Service must be specified."));
Variant vservice = arguments[0];
if (!vservice.IsObjectType<ConfigObject>())
throw invalid_argument("Argument must be a config object.");
throw_exception(invalid_argument("Argument must be a config object."));
Service service = static_cast<ConfigObject::Ptr>(vservice);

View File

@ -24,7 +24,7 @@ using namespace icinga;
void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments)
{
if (arguments.size() < 1)
throw invalid_argument("Missing argument: Service must be specified.");
throw_exception(invalid_argument("Missing argument: Service must be specified."));
time_t now;
time(&now);

View File

@ -47,7 +47,7 @@ Service Service::GetByName(const string& name)
ConfigObject::Ptr configObject = ConfigObject::GetObject("service", name);
if (!configObject)
throw invalid_argument("Service '" + name + "' does not exist.");
throw_exception(invalid_argument("Service '" + name + "' does not exist."));
return configObject;
}
@ -56,7 +56,7 @@ Host Service::GetHost(void) const
{
string hostname;
if (!GetProperty("host_name", &hostname))
throw runtime_error("Service object is missing the 'host_name' property.");
throw_exception(runtime_error("Service object is missing the 'host_name' property."));
return Host::GetByName(hostname);
}
@ -269,7 +269,7 @@ CheckResult Service::GetLastCheckResult(void) const
{
Dictionary::Ptr value;
if (!GetTag("last_result", &value))
throw invalid_argument("Service has no last check result.");
throw_exception(invalid_argument("Service has no last check result."));
return CheckResult(value);
}

View File

@ -62,7 +62,7 @@ ServiceGroup ServiceGroup::GetByName(const string& name)
ConfigObject::Ptr configObject = ConfigObject::GetObject("hostgroup", name);
if (!configObject)
throw invalid_argument("ServiceGroup '" + name + "' does not exist.");
throw_exception(invalid_argument("ServiceGroup '" + name + "' does not exist."));
return ServiceGroup(configObject);
}

View File

@ -249,7 +249,7 @@ void CIBSyncComponent::RemoteObjectCommittedHandler(const Endpoint::Ptr& sender,
}
if (object->IsLocal())
throw invalid_argument("Replicated remote object is marked as local.");
throw_exception(invalid_argument("Replicated remote object is marked as local."));
if (object->GetSource().empty())
object->SetSource(sender->GetIdentity());

View File

@ -34,7 +34,7 @@ void ConfigFileComponent::Start(void)
string filename;
if (!GetConfig()->GetProperty("configFilename", &filename))
throw logic_error("Missing 'configFilename' property");
throw_exception(logic_error("Missing 'configFilename' property"));
vector<ConfigItem::Ptr> configItems = ConfigCompiler::CompileFile(filename);

View File

@ -139,7 +139,7 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
CopyServiceAttributes(host, service, builder);
} else {
throw invalid_argument("Service description must be either a string or a dictionary.");
throw_exception(invalid_argument("Service description must be either a string or a dictionary."));
}
ConfigItem::Ptr serviceItem = builder->Compile();

View File

@ -1801,7 +1801,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yysc
if ( ! b )
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
/* It's okay to grow etc. this buffer, and we should throw it
/* It's okay to grow etc. this buffer, and we should throw_exception it
* away when we're done.
*/
b->yy_is_our_buffer = 1;

View File

@ -212,7 +212,7 @@ void yyerror(YYLTYPE *locp, ConfigCompiler *context, const char *err)
{
stringstream message;
message << *locp << ": " << err;
throw runtime_error(message.str());
throw_exception(runtime_error(message.str()));
}
int yyparse(ConfigCompiler *context);

View File

@ -70,7 +70,7 @@ void yyerror(YYLTYPE *locp, ConfigCompiler *context, const char *err)
{
stringstream message;
message << *locp << ": " << err;
throw runtime_error(message.str());
throw_exception(runtime_error(message.str()));
}
int yyparse(ConfigCompiler *context);

View File

@ -72,11 +72,10 @@ vector<ConfigItem::Ptr> ConfigCompiler::CompileStream(const string& path, istrea
vector<ConfigItem::Ptr> ConfigCompiler::CompileFile(const string& path)
{
ifstream stream;
stream.exceptions(ifstream::badbit);
stream.open(path.c_str(), ifstream::in);
if (!stream.good())
throw invalid_argument("Could not open config file: " + path);
throw_exception(invalid_argument("Could not open config file: " + path));
Logger::Write(LogInformation, "dyn", "Compiling config file: " + path);

View File

@ -62,7 +62,7 @@ void ConfigItem::CalculateProperties(Dictionary::Ptr dictionary) const
if (!parent) {
stringstream message;
message << "Parent object '" << name << "' does not exist (" << m_DebugInfo << ")";
throw domain_error(message.str());
throw_exception(domain_error(message.str()));
}
parent->CalculateProperties(dictionary);

View File

@ -45,7 +45,7 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
switch (m_Operator) {
case OperatorExecute:
if (!valueExprl)
throw invalid_argument("Operand for OperatorExecute must be an ExpressionList.");
throw_exception(invalid_argument("Operand for OperatorExecute must be an ExpressionList."));
valueExprl->Execute(dictionary);
@ -70,7 +70,7 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
if (!oldValue.IsEmpty()) {
stringstream message;
message << "Wrong argument types for += (non-dictionary and dictionary) (" << m_DebugInfo << ")";
throw domain_error(message.str());
throw_exception(domain_error(message.str()));
}
dict = boost::make_shared<Dictionary>();
@ -89,13 +89,13 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
} else {
stringstream message;
message << "+= only works for dictionaries (" << m_DebugInfo << ")";
throw domain_error(message.str());
throw_exception(domain_error(message.str()));
}
break;
default:
throw runtime_error("Not yet implemented.");
throw_exception(runtime_error("Not yet implemented."));
}
dictionary->Set(m_Key, newValue);

View File

@ -82,7 +82,7 @@ shared_ptr<SSL_CTX> EndpointManager::GetSSLContext(void) const
void EndpointManager::AddListener(string service)
{
if (!GetSSLContext())
throw logic_error("SSL context is required for AddListener()");
throw_exception(logic_error("SSL context is required for AddListener()"));
stringstream s;
s << "Adding new listener: port " << service;
@ -237,7 +237,7 @@ void EndpointManager::SendAnycastMessage(Endpoint::Ptr sender,
{
string method;
if (!message.GetMethod(&method))
throw invalid_argument("Message is missing the 'method' property.");
throw_exception(invalid_argument("Message is missing the 'method' property."));
vector<Endpoint::Ptr> candidates;
Endpoint::Ptr endpoint;
@ -269,11 +269,11 @@ void EndpointManager::SendMulticastMessage(Endpoint::Ptr sender,
{
string id;
if (message.GetID(&id))
throw invalid_argument("Multicast requests must not have an ID.");
throw_exception(invalid_argument("Multicast requests must not have an ID."));
string method;
if (!message.GetMethod(&method))
throw invalid_argument("Message is missing the 'method' property.");
throw_exception(invalid_argument("Message is missing the 'method' property."));
Endpoint::Ptr recipient;
BOOST_FOREACH(tie(tuples::ignore, recipient), m_Endpoints) {
@ -366,7 +366,7 @@ void EndpointManager::ProcessResponseMessage(const Endpoint::Ptr& sender, const
{
string id;
if (!message.GetID(&id))
throw invalid_argument("Response message must have a message ID.");
throw_exception(invalid_argument("Response message must have a message ID."));
map<string, PendingRequest>::iterator it;
it = m_Requests.find(id);

View File

@ -97,7 +97,7 @@ int IcingaApplication::Main(const vector<string>& args)
continue;
} else if (arg == "-L") {
if (it + 1 == args.end())
throw invalid_argument("Option -L requires a parameter");
throw_exception(invalid_argument("Option -L requires a parameter"));
StreamLogger::Ptr fileLogger = boost::make_shared<StreamLogger>(LogInformation);
fileLogger->OpenFile(*(it + 1));
@ -110,25 +110,25 @@ int IcingaApplication::Main(const vector<string>& args)
daemonize = true;
continue;
} else {
throw invalid_argument("Unknown option: " + arg);
throw_exception(invalid_argument("Unknown option: " + arg));
}
}
configFile = arg;
if (it + 1 != args.end())
throw invalid_argument("Trailing command line arguments after config filename.");
throw_exception(invalid_argument("Trailing command line arguments after config filename."));
}
if (configFile.empty())
throw invalid_argument("No config file was specified on the command line.");
throw_exception(invalid_argument("No config file was specified on the command line."));
if (enableSyslog) {
#ifndef _WIN32
SyslogLogger::Ptr syslogLogger = boost::make_shared<SyslogLogger>(LogInformation);
Logger::RegisterLogger(syslogLogger);
#else /* _WIN32 */
throw invalid_argument("Syslog is not supported on Windows.");
throw_exception(invalid_argument("Syslog is not supported on Windows."));
#endif /* _WIN32 */
}
@ -160,10 +160,10 @@ int IcingaApplication::Main(const vector<string>& args)
ConfigObject::Ptr icingaConfig = ConfigObject::GetObject("application", "icinga");
if (!icingaConfig)
throw runtime_error("Configuration must contain an 'application' object named 'icinga'.");
throw_exception(runtime_error("Configuration must contain an 'application' object named 'icinga'."));
if (!icingaConfig->IsLocal())
throw runtime_error("'icinga' application object must be 'local'.");
throw_exception(runtime_error("'icinga' application object must be 'local'."));
icingaConfig->GetProperty("cert", &m_CertificateFile);
icingaConfig->GetProperty("ca", &m_CAFile);
@ -217,7 +217,7 @@ void IcingaApplication::NewComponentHandler(const ConfigObject::Ptr& object)
{
/* don't allow replicated config objects */
if (!object->IsLocal())
throw runtime_error("'component' objects must be 'local'");
throw_exception(runtime_error("'component' objects must be 'local'"));
string path;
if (!object->GetProperty("path", &path)) {
@ -235,7 +235,7 @@ void IcingaApplication::NewLogHandler(const ConfigObject::Ptr& object)
{
/* don't allow replicated config objects */
if (!object->IsLocal())
throw runtime_error("'log' objects must be 'local'");
throw_exception(runtime_error("'log' objects must be 'local'"));
Logger::Ptr logger;
if (object->GetTag("logger", &logger))
@ -243,7 +243,7 @@ void IcingaApplication::NewLogHandler(const ConfigObject::Ptr& object)
string type;
if (!object->GetProperty("type", &type))
throw invalid_argument("'log' object must have a 'type' property");
throw_exception(invalid_argument("'log' object must have a 'type' property"));
string strSeverity;
LogSeverity severity = LogInformation;
@ -254,12 +254,12 @@ void IcingaApplication::NewLogHandler(const ConfigObject::Ptr& object)
#ifndef _WIN32
logger = boost::make_shared<SyslogLogger>(severity);
#else /* _WIN32 */
throw invalid_argument("Syslog is not supported on Windows.");
throw_exception(invalid_argument("Syslog is not supported on Windows."));
#endif /* _WIN32 */
} else if (type == "file") {
string path;
if (!object->GetProperty("path", &path))
throw invalid_argument("'log' object of type 'file' must have a 'path' property");
throw_exception(invalid_argument("'log' object of type 'file' must have a 'path' property"));
StreamLogger::Ptr slogger = boost::make_shared<StreamLogger>(severity);
slogger->OpenFile(path);
@ -268,7 +268,7 @@ void IcingaApplication::NewLogHandler(const ConfigObject::Ptr& object)
} else if (type == "console") {
logger = boost::make_shared<StreamLogger>(&std::cout, severity);
} else {
throw runtime_error("Unknown log type: " + type);
throw_exception(runtime_error("Unknown log type: " + type));
}
object->SetTag("logger", logger);

View File

@ -52,7 +52,6 @@ void JsonRpcEndpoint::SetClient(JsonRpcClient::Ptr client)
m_Client = client;
client->OnNewMessage.connect(boost::bind(&JsonRpcEndpoint::NewMessageHandler, this, _2));
client->OnClosed.connect(boost::bind(&JsonRpcEndpoint::ClientClosedHandler, this));
client->OnError.connect(boost::bind(&JsonRpcEndpoint::ClientErrorHandler, this, _2));
client->OnCertificateValidated.connect(boost::bind(&JsonRpcEndpoint::CertificateValidatedHandler, this));
}
@ -63,7 +62,7 @@ bool JsonRpcEndpoint::IsLocal(void) const
bool JsonRpcEndpoint::IsConnected(void) const
{
return (bool)m_Client;
return (m_Client && m_Client->IsConnected());
}
void JsonRpcEndpoint::ProcessRequest(Endpoint::Ptr sender, const RequestMessage& message)
@ -109,6 +108,15 @@ void JsonRpcEndpoint::NewMessageHandler(const MessagePart& message)
void JsonRpcEndpoint::ClientClosedHandler(void)
{
try {
m_Client->CheckException();
} catch (const exception& ex) {
stringstream message;
message << "Error occured for JSON-RPC socket: Message=" << ex.what();
Logger::Write(LogWarning, "jsonrpc", message.str());
}
Logger::Write(LogWarning, "jsonrpc", "Lost connection to endpoint: identity=" + GetIdentity());
// TODO: _only_ clear non-persistent publications/subscriptions
@ -129,10 +137,6 @@ void JsonRpcEndpoint::ClientClosedHandler(void)
void JsonRpcEndpoint::ClientErrorHandler(const exception& ex)
{
stringstream message;
message << "Error occured for JSON-RPC socket: Message=" << ex.what();
Logger::Write(LogWarning, "jsonrpc", message.str());
}
void JsonRpcEndpoint::CertificateValidatedHandler(void)

View File

@ -68,7 +68,7 @@ void VirtualEndpoint::UnregisterTopicHandler(string topic, function<void (const
//m_TopicHandlers[method] -= callback;
//UnregisterMethodSubscription(method);
throw NotImplementedException();
throw_exception(NotImplementedException());
}
void VirtualEndpoint::ProcessRequest(Endpoint::Ptr sender, const RequestMessage& request)

View File

@ -41,7 +41,7 @@ MessagePart::MessagePart(string jsonString)
json_t *json = cJSON_Parse(jsonString.c_str());
if (!json)
throw runtime_error("Invalid JSON string");
throw_exception(runtime_error("Invalid JSON string"));
m_Dictionary = GetDictionaryFromJson(json);

View File

@ -43,12 +43,16 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str)
buffer_length = 16;
char *buffer = (char *)malloc(buffer_length);
if (buffer == NULL && buffer_length > 0)
throw_exception(bad_alloc());
queue->Peek(buffer, buffer_length);
/* no leading zeros allowed */
if (buffer[0] == '0' && isdigit(buffer[1])) {
free(buffer);
throw invalid_argument("Invalid netstring (leading zero)");
throw_exception(invalid_argument("Invalid netstring (leading zero)"));
}
size_t len, i;
@ -58,7 +62,7 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str)
/* length specifier must have at most 9 characters */
if (i >= 9) {
free(buffer);
throw invalid_argument("Length specifier must not exceed 9 characters");
throw_exception(invalid_argument("Length specifier must not exceed 9 characters"));
}
len = len * 10 + (buffer[i] - '0');
@ -77,7 +81,7 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str)
if (new_buffer == NULL) {
free(buffer);
throw std::bad_alloc();
throw_exception(bad_alloc());
}
buffer = new_buffer;
@ -87,13 +91,13 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str)
/* check for the colon delimiter */
if (buffer[i] != ':') {
free(buffer);
throw invalid_argument("Invalid Netstring (missing :)");
throw_exception(invalid_argument("Invalid Netstring (missing :)"));
}
/* check for the comma delimiter after the string */
if (buffer[i + 1 + len] != ',') {
free(buffer);
throw invalid_argument("Invalid Netstring (missing ,)");
throw_exception(invalid_argument("Invalid Netstring (missing ,)"));
}
*str = string(&buffer[i + 1], &buffer[i + 1 + len]);