diff --git a/lib/base/exception.cpp b/lib/base/exception.cpp index c694b6bf2..cb505b04b 100644 --- a/lib/base/exception.cpp +++ b/lib/base/exception.cpp @@ -2,6 +2,7 @@ #include "base/exception.hpp" #include +#include #ifdef _WIN32 # include "base/utility.hpp" @@ -425,3 +426,19 @@ std::string icinga::to_string(const ContextTraceErrorInfo& e) msgbuf << "[Context] = " << e.value(); return msgbuf.str(); } + +invalid_downtime_removal_error::invalid_downtime_removal_error(String message) + : m_Message(std::move(message)) +{ } + +invalid_downtime_removal_error::invalid_downtime_removal_error(const char *message) + : m_Message(message) +{ } + +invalid_downtime_removal_error::~invalid_downtime_removal_error() noexcept +{ } + +const char *invalid_downtime_removal_error::what() const noexcept +{ + return m_Message.CStr(); +} diff --git a/lib/base/exception.hpp b/lib/base/exception.hpp index 246c28a78..7cc0ce7c7 100644 --- a/lib/base/exception.hpp +++ b/lib/base/exception.hpp @@ -122,6 +122,19 @@ std::string to_string(const errinfo_getaddrinfo_error& e); struct errinfo_message_; typedef boost::error_info errinfo_message; +class invalid_downtime_removal_error : virtual public std::exception, virtual public boost::exception { +public: + explicit invalid_downtime_removal_error(String message); + explicit invalid_downtime_removal_error(const char* message); + + ~invalid_downtime_removal_error() noexcept override; + + const char *what() const noexcept final; + +private: + String m_Message; +}; + } #endif /* EXCEPTION_H */ diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp index afd53e981..2fc4caaf3 100644 --- a/lib/icinga/apiactions.cpp +++ b/lib/icinga/apiactions.cpp @@ -493,7 +493,13 @@ Dictionary::Ptr ApiActions::RemoveDowntime(const ConfigObject::Ptr& object, downtime->SetRemovedBy(author); } - Downtime::RemoveDowntime(downtime->GetName(), true); + try { + Downtime::RemoveDowntime(downtime->GetName(), true); + } catch (const invalid_downtime_removal_error& error) { + Log(LogWarning, "ApiActions") << error.what(); + + return ApiActions::CreateResult(400, error.what()); + } } return ApiActions::CreateResult(200, "Successfully removed all downtimes for object '" + checkable->GetName() + "'."); @@ -509,11 +515,17 @@ Dictionary::Ptr ApiActions::RemoveDowntime(const ConfigObject::Ptr& object, downtime->SetRemovedBy(author); } - String downtimeName = downtime->GetName(); + try { + String downtimeName = downtime->GetName(); - Downtime::RemoveDowntime(downtimeName, true); + Downtime::RemoveDowntime(downtimeName, true); - return ApiActions::CreateResult(200, "Successfully removed downtime '" + downtimeName + "'."); + return ApiActions::CreateResult(200, "Successfully removed downtime '" + downtimeName + "'."); + } catch (const invalid_downtime_removal_error& error) { + Log(LogWarning, "ApiActions") << error.what(); + + return ApiActions::CreateResult(400, error.what()); + } } Dictionary::Ptr ApiActions::ShutdownProcess(const ConfigObject::Ptr& object, diff --git a/lib/icinga/downtime.cpp b/lib/icinga/downtime.cpp index 1364f722c..c327d0dd2 100644 --- a/lib/icinga/downtime.cpp +++ b/lib/icinga/downtime.cpp @@ -317,9 +317,8 @@ void Downtime::RemoveDowntime(const String& id, bool cancelled, bool expired, co String config_owner = downtime->GetConfigOwner(); if (!config_owner.IsEmpty() && !expired) { - Log(LogWarning, "Downtime") - << "Cannot remove downtime '" << downtime->GetName() << "'. It is owned by scheduled downtime object '" << config_owner << "'"; - return; + BOOST_THROW_EXCEPTION(invalid_downtime_removal_error("Cannot remove downtime '" + downtime->GetName() + + "'. It is owned by scheduled downtime object '" + config_owner + "'")); } downtime->SetWasCancelled(cancelled); diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index e974a0175..dcf3d1bc4 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -970,10 +970,16 @@ void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vector& arguments) { int id = Convert::ToLong(arguments[0]); - Log(LogNotice, "ExternalCommandProcessor") - << "Removing downtime ID " << arguments[0]; String rid = Downtime::GetDowntimeIDFromLegacyID(id); - Downtime::RemoveDowntime(rid, true); + + try { + Downtime::RemoveDowntime(rid, true); + + Log(LogNotice, "ExternalCommandProcessor") + << "Removed downtime ID " << arguments[0]; + } catch (const invalid_downtime_removal_error& error) { + Log(LogWarning, "ExternalCommandProcessor") << error.what(); + } } void ExternalCommandProcessor::ScheduleHostDowntime(double, const std::vector& arguments) @@ -1072,10 +1078,16 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double, void ExternalCommandProcessor::DelHostDowntime(double, const std::vector& arguments) { int id = Convert::ToLong(arguments[0]); - Log(LogNotice, "ExternalCommandProcessor") - << "Removing downtime ID " << arguments[0]; String rid = Downtime::GetDowntimeIDFromLegacyID(id); - Downtime::RemoveDowntime(rid, true); + + try { + Downtime::RemoveDowntime(rid, true); + + Log(LogNotice, "ExternalCommandProcessor") + << "Removed downtime ID " << arguments[0]; + } catch (const invalid_downtime_removal_error& error) { + Log(LogWarning, "ExternalCommandProcessor") << error.what(); + } } void ExternalCommandProcessor::DelDowntimeByHostName(double, const std::vector& arguments) @@ -1102,10 +1114,15 @@ void ExternalCommandProcessor::DelDowntimeByHostName(double, const std::vectorGetDowntimes()) { - Log(LogNotice, "ExternalCommandProcessor") - << "Removing downtime '" << downtime->GetName() << "'."; + try { + String downtimeName = downtime->GetName(); + Downtime::RemoveDowntime(downtimeName, true); - Downtime::RemoveDowntime(downtime->GetName(), true); + Log(LogNotice, "ExternalCommandProcessor") + << "Removed downtime '" << downtimeName << "'."; + } catch (const invalid_downtime_removal_error& error) { + Log(LogWarning, "ExternalCommandProcessor") << error.what(); + } } for (const Service::Ptr& service : host->GetServices()) { @@ -1119,10 +1136,15 @@ void ExternalCommandProcessor::DelDowntimeByHostName(double, const std::vectorGetComment() != commentString) continue; - Log(LogNotice, "ExternalCommandProcessor") - << "Removing downtime '" << downtime->GetName() << "'."; + try { + String downtimeName = downtime->GetName(); + Downtime::RemoveDowntime(downtimeName, true); - Downtime::RemoveDowntime(downtime->GetName(), true); + Log(LogNotice, "ExternalCommandProcessor") + << "Removed downtime '" << downtimeName << "'."; + } catch (const invalid_downtime_removal_error& error) { + Log(LogWarning, "ExternalCommandProcessor") << error.what(); + } } } }