diff --git a/include/utils/error/error_exceptions.hpp b/include/utils/error/error_exceptions.hpp deleted file mode 100644 index 0bac370c..00000000 --- a/include/utils/error/error_exceptions.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Pionix GmbH and Contributors to EVerest - -#ifndef UTILS_ERROR_EXCEPTIONS_HPP -#define UTILS_ERROR_EXCEPTIONS_HPP - -#include -#include - -#include -namespace Everest { -namespace error { - -class EverestNotValidErrorTypeError : public EverestBaseRuntimeError { -public: - explicit EverestNotValidErrorTypeError(const ErrorType& error_type_) : - EverestBaseRuntimeError("Error type " + error_type_ + " is not valid."){}; -}; - -class EverestAlreadyExistsError : public EverestBaseLogicError { -public: - using EverestBaseLogicError::EverestBaseLogicError; -}; - -class EverestNotAllowedError : public EverestBaseLogicError { -public: - using EverestBaseLogicError::EverestBaseLogicError; -}; - -class EverestInterfaceMissingDeclartionError : public EverestBaseLogicError { -public: - using EverestBaseLogicError::EverestBaseLogicError; -}; - -class EverestDirectoryNotFoundError : public EverestBaseRuntimeError { -public: - using EverestBaseRuntimeError::EverestBaseRuntimeError; -}; - -class EverestParseError : public EverestBaseRuntimeError { -public: - using EverestBaseRuntimeError::EverestBaseRuntimeError; -}; - -class EverestArgumentError : public EverestBaseLogicError { -public: - using EverestBaseLogicError::EverestBaseLogicError; -}; - -} // namespace error -} // namespace Everest - -#endif // UTILS_ERROR_EXCEPTIONS_HPP diff --git a/lib/error/error.cpp b/lib/error/error.cpp index 2806263c..3b283563 100644 --- a/lib/error/error.cpp +++ b/lib/error/error.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include namespace Everest { namespace error { @@ -76,7 +76,8 @@ std::string severity_to_string(const Severity& s) { case Severity::High: return "High"; } - throw std::out_of_range("No known string conversion for provided enum of type Severity."); + EVLOG_error << "No known string conversion for provided enum of type Severity. Defaulting to High."; + return "High"; } Severity string_to_severity(const std::string& s) { @@ -87,7 +88,8 @@ Severity string_to_severity(const std::string& s) { } else if (s == "High") { return Severity::High; } - throw std::out_of_range("Provided string " + s + " could not be converted to enum of type Severity."); + EVLOG_error << "Provided string " << s << " could not be converted to enum of type Severity. Defaulting to High."; + return Severity::High; } std::string state_to_string(const State& s) { @@ -99,7 +101,8 @@ std::string state_to_string(const State& s) { case State::ClearedByReboot: return "ClearedByReboot"; } - throw std::out_of_range("No known string conversion for provided enum of type State."); + EVLOG_error << "No known string conversion for provided enum of type State. Defaulting to Active."; + return "Active"; } State string_to_state(const std::string& s) { @@ -110,7 +113,8 @@ State string_to_state(const std::string& s) { } else if (s == "ClearedByReboot") { return State::ClearedByReboot; } - throw std::out_of_range("Provided string " + s + " could not be converted to enum of type State."); + EVLOG_error << "Provided string " << s << " could not be converted to enum of type State. Defaulting to Active."; + return State::Active; } } // namespace error diff --git a/lib/error/error_database_map.cpp b/lib/error/error_database_map.cpp index 062df9f3..71ce4aea 100644 --- a/lib/error/error_database_map.cpp +++ b/lib/error/error_database_map.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -16,8 +15,8 @@ namespace error { void ErrorDatabaseMap::add_error(ErrorPtr error) { std::lock_guard lock(this->errors_mutex); if (this->errors.find(error->uuid) != this->errors.end()) { - throw EverestAlreadyExistsError("Error with handle " + error->uuid.to_string() + - " already exists in ErrorDatabaseMap."); + EVLOG_error << "Error with handle " << error->uuid.to_string() << " already exists in ErrorDatabaseMap."; + return; } this->errors[error->uuid] = error; } @@ -60,7 +59,8 @@ std::list ErrorDatabaseMap::get_errors_no_mutex(const std::listseverity < Severity::High; } break; } - throw std::out_of_range("No known condition for provided enum of type SeverityFilter."); + EVLOG_error << "No known condition for provided enum of type SeverityFilter."; + return false; }; } break; case FilterType::TimePeriod: { @@ -79,7 +79,8 @@ std::list ErrorDatabaseMap::get_errors_no_mutex(const std::listvendor_id != filter.get_vendor_id_filter().value; }; } break; default: - throw std::out_of_range("No known pred for provided enum of type FilterType."); + EVLOG_error << "No known pred for provided enum of type FilterType. Ignoring."; + return result; } result.remove_if(pred); } diff --git a/lib/error/error_filter.cpp b/lib/error/error_filter.cpp index 29aee1b9..508b4185 100644 --- a/lib/error/error_filter.cpp +++ b/lib/error/error_filter.cpp @@ -1,10 +1,10 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Pionix GmbH and Contributors to EVerest -#include #include #include +#include namespace Everest { namespace error { @@ -26,7 +26,8 @@ std::string severity_filter_to_string(const SeverityFilter& f) { case SeverityFilter::HIGH_GE: return "HIGH_GE"; } - throw std::out_of_range("No known string conversion for provided enum of type SeverityFilter."); + EVLOG_error << "No known string conversion for provided enum of type SeverityFilter. Defaulting to HIGH_GE"; + return "HIGH_GE"; } SeverityFilter string_to_severity_filter(const std::string& s) { @@ -37,7 +38,9 @@ SeverityFilter string_to_severity_filter(const std::string& s) { } else if (s == "HIGH_GE") { return SeverityFilter::HIGH_GE; } - throw std::out_of_range("Provided string " + s + " could not be converted to enum of type SeverityFilter."); + EVLOG_error << "Provided string " << s + << " could not be converted to enum of type SeverityFilter. Defaulting to HIGH_GE"; + return SeverityFilter::HIGH_GE; } TypeFilter::TypeFilter(const ErrorType& value_) : value(value_) { @@ -68,7 +71,8 @@ std::string filter_type_to_string(const FilterType& f) { case FilterType::VendorId: return "VendorId"; } - throw std::out_of_range("No known string conversion for provided enum of type FilterType."); + EVLOG_error << "No known string conversion for provided enum of type FilterType. Defaulting to Type"; + return "Type"; } FilterType string_to_filter_type(const std::string& s) { @@ -89,7 +93,8 @@ FilterType string_to_filter_type(const std::string& s) { } else if (s == "VendorId") { return FilterType::VendorId; } - throw std::out_of_range("Provided string " + s + " could not be converted to enum of type FilterType."); + EVLOG_error << "Provided string " << s << " could not be converted to enum of type FilterType. Deafulting to Type."; + return FilterType::Type; } ErrorFilter::ErrorFilter() = default; @@ -99,56 +104,67 @@ ErrorFilter::ErrorFilter(const FilterVariant& filter_) : filter(filter_) { FilterType ErrorFilter::get_filter_type() const { if (filter.index() == 0) { - throw EverestBaseLogicError("Filter type is not set."); + EVLOG_error << "Filter type is not set. Defaulting to 'FilterType::State'."; + return FilterType::State; } return static_cast(filter.index()); } StateFilter ErrorFilter::get_state_filter() const { if (this->get_filter_type() != FilterType::State) { - throw EverestBaseLogicError("Filter type is not StateFilter."); + EVLOG_error << "Filter type is not StateFilter. Defaulting to 'StateFilter::Active'."; + return StateFilter::Active; } return std::get(filter); } OriginFilter ErrorFilter::get_origin_filter() const { if (this->get_filter_type() != FilterType::Origin) { - throw EverestBaseLogicError("Filter type is not OriginFilter."); + EVLOG_error << "Filter type is not OriginFilter. Defaulting to " + "'OriginFilter::ImplementationIdentifier(\"no-module-id-provided\", " + "\"no-implementation-id-provided\")'."; + return OriginFilter(ImplementationIdentifier("no-module-id-provided", "no-implementation-id-provided")); } return std::get(filter); } TypeFilter ErrorFilter::get_type_filter() const { if (this->get_filter_type() != FilterType::Type) { - throw EverestBaseLogicError("Filter type is not TypeFilter."); + EVLOG_error << "Filter type is not TypeFilter. Defaulting to 'TypeFilter(\"no-type-provided\")'."; + return TypeFilter("no-type-provided"); } return std::get(filter); } SeverityFilter ErrorFilter::get_severity_filter() const { if (this->get_filter_type() != FilterType::Severity) { - throw EverestBaseLogicError("Filter type is not SeverityFilter."); + EVLOG_error << "Filter type is not SeverityFilter. Defaulting to 'SeverityFilter::HIGH_GE'."; + return SeverityFilter::HIGH_GE; } return std::get(filter); } TimePeriodFilter ErrorFilter::get_time_period_filter() const { if (this->get_filter_type() != FilterType::TimePeriod) { - throw EverestBaseLogicError("Filter type is not TimePeriodFilter."); + EVLOG_error << "Filter type is not TimePeriodFilter. Defaulting to 'TimePeriodFilter{Error::time_point(), " + "Error::time_point()}'."; + return TimePeriodFilter{Error::time_point(), Error::time_point()}; } return std::get(filter); } HandleFilter ErrorFilter::get_handle_filter() const { if (this->get_filter_type() != FilterType::Handle) { - throw EverestBaseLogicError("Filter type is not HandleFilter."); + EVLOG_error << "Filter type is not HandleFilter. Defaulting to 'HandleFilter()'."; + return HandleFilter(); } return std::get(filter); } SubTypeFilter ErrorFilter::get_sub_type_filter() const { if (this->get_filter_type() != FilterType::SubType) { - throw EverestBaseLogicError("Filter type is not SubTypeFilter."); + EVLOG_error << "Filter type is not SubTypeFilter. Defaulting to 'SubTypeFilter(\"no-sub-type-provided\")'."; + return SubTypeFilter("no-sub-type-provided"); } return std::get(filter); } diff --git a/lib/error/error_manager_impl.cpp b/lib/error/error_manager_impl.cpp index a311c438..52a6355b 100644 --- a/lib/error/error_manager_impl.cpp +++ b/lib/error/error_manager_impl.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -28,16 +27,21 @@ ErrorManagerImpl::ErrorManagerImpl(std::shared_ptr error_type_map_ publish_raised_error(publish_raised_error_), publish_cleared_error(publish_cleared_error_), validate_error_types(validate_error_types_) { + if (validate_error_types) { + for (const ErrorType& type : allowed_error_types) { + if (!error_type_map->has(type)) { + EVLOG_error << "Error type '" << type << "' in allowed_error_types is not defined, ignored."; + } + } + } } void ErrorManagerImpl::raise_error(const Error& error) { if (validate_error_types) { if (std::find(allowed_error_types.begin(), allowed_error_types.end(), error.type) == allowed_error_types.end()) { - throw EverestArgumentError("Error type " + error.type + " is not allowed to be raised."); - } - if (!this->error_type_map->has(error.type)) { - throw EverestArgumentError("Error type " + error.type + " is not known."); + EVLOG_error << "Error type " << error.type << " is not allowed to be raised. Ignoring."; + return; } } if (!can_be_raised(error.type, error.sub_type)) { @@ -81,7 +85,8 @@ std::list ErrorManagerImpl::clear_error(const ErrorType& type, const E std::list filters = {ErrorFilter(TypeFilter(type)), ErrorFilter(SubTypeFilter(sub_type))}; std::list res = database->remove_errors(filters); if (res.size() > 1) { - throw EverestBaseLogicError("There are more than one matching error, this is not valid"); + EVLOG_error << "There are more than one matching error, this is not valid"; + return {}; } const ErrorPtr error = res.front(); error->state = State::ClearedByModule; diff --git a/lib/error/error_manager_req.cpp b/lib/error/error_manager_req.cpp index 0e850502..1d103527 100644 --- a/lib/error/error_manager_req.cpp +++ b/lib/error/error_manager_req.cpp @@ -5,11 +5,9 @@ #include #include -#include #include #include -#include #include namespace Everest { @@ -22,6 +20,12 @@ ErrorManagerReq::ErrorManagerReq(std::shared_ptr error_type_map_, database(error_database_), allowed_error_types(allowed_error_types_), subscribe_error_func(subscribe_error_func_) { + + for (const ErrorType& type : allowed_error_types) { + if (!error_type_map->has(type)) { + EVLOG_error << "Error type '" << type << "' in allowed_error_types is not defined, ignored."; + } + } ErrorCallback on_raise = [this](const Error& error) { this->on_error_raised(error); }; ErrorCallback on_clear = [this](const Error& error) { this->on_error_cleared(error); }; for (const ErrorType& type : allowed_error_types) { @@ -54,11 +58,13 @@ void ErrorManagerReq::subscribe_all_errors(const ErrorCallback& callback, const void ErrorManagerReq::on_error_raised(const Error& error) { if (std::find(allowed_error_types.begin(), allowed_error_types.end(), error.type) == allowed_error_types.end()) { - throw EverestBaseLogicError("Error can't be raised by module_id " + error.origin.module_id + - " and implemenetation_id " + error.origin.implementation_id); + EVLOG_error << "Error can't be raised by module_id " << error.origin.module_id << " and implemenetation_id " + << error.origin.implementation_id << ", ignored."; + return; } if (!error_type_map->has(error.type)) { - throw EverestBaseLogicError("Error type '" + error.type + "' is not defined"); + EVLOG_error << "Error type '" << error.type << "' is not defined, ignored."; + return; } database->add_error(std::make_shared(error)); on_error(error, true); @@ -68,11 +74,13 @@ void ErrorManagerReq::on_error_cleared(const Error& error) { std::list filters = {ErrorFilter(TypeFilter(error.type)), ErrorFilter(SubTypeFilter(error.sub_type))}; std::list res = database->remove_errors(filters); if (res.size() < 1) { - throw EverestBaseLogicError("Error wasn't raised, type: " + error.type + ", sub_type: " + error.sub_type); + EVLOG_error << "Error wasn't raised, type: " << error.type << ", sub_type: " << error.sub_type << ", ignored."; + return; } if (res.size() > 1) { - throw EverestBaseLogicError("More than one error is cleared, type: " + error.type + - ", sub_type: " + error.sub_type); + EVLOG_error << "More than one error is cleared, type: " << error.type << ", sub_type: " << error.sub_type + << ", ignored."; + return; } on_error(error, false); diff --git a/lib/error/error_type_map.cpp b/lib/error/error_type_map.cpp index f123894d..a501b71b 100644 --- a/lib/error/error_type_map.cpp +++ b/lib/error/error_type_map.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -20,8 +19,9 @@ void ErrorTypeMap::load_error_types(std::filesystem::path error_types_dir) { BOOST_LOG_FUNCTION(); if (!std::filesystem::is_directory(error_types_dir) || !std::filesystem::exists(error_types_dir)) { - throw EverestDirectoryNotFoundError( - fmt::format("Error types directory '{}' does not exist.", error_types_dir.string())); + EVLOG_error << "Error types directory '" << error_types_dir.string() + << "' does not exist, error types not loaded."; + return; } for (const auto& entry : std::filesystem::directory_iterator(error_types_dir)) { if (!entry.is_regular_file()) { @@ -37,32 +37,44 @@ void ErrorTypeMap::load_error_types(std::filesystem::path error_types_dir) { continue; } if (!error_type_file.at("errors").is_array()) { - throw EverestParseError(fmt::format("Error type file '{}' does not contain an array with key 'errors'.", - entry.path().string())); + EVLOG_error << "Error type file '" << entry.path().string() + << "' does not contain an array with key 'errors', skipped."; + continue; } for (const auto& error : error_type_file["errors"]) { if (!error.contains("name")) { - throw EverestParseError( - fmt::format("Error type file '{}' contains an error without a 'name' key.", entry.path().string())); + EVLOG_error << "Error type file '" << entry.path().string() + << "' contains an error without a 'name' key, skipped."; + continue; } + std::string description; if (!error.contains("description")) { - throw EverestParseError(fmt::format( - "Error type file '{}' contains an error without a 'description' key.", entry.path().string())); + EVLOG_error << "Error type file '" << entry.path().string() + << "' contains an error without a 'description' key, using default description"; + description = "No description found"; + } else { + description = error.at("description").get(); } ErrorType complete_name = prefix + "/" + error.at("name").get(); if (this->has(complete_name)) { - throw EverestAlreadyExistsError( - fmt::format("Error type file '{}' contains an error with the name '{}' which is already defined.", - entry.path().string(), complete_name)); + EVLOG_error << "Error type file '" << entry.path().string() << "' contains an error with the name '" + << complete_name << "' which is already defined, skipped."; + continue; } - std::string description = error.at("description").get(); error_types[complete_name] = description; } } } std::string ErrorTypeMap::get_description(const ErrorType& error_type) const { - return error_types.at(error_type); + std::string description; + try { + description = error_types.at(error_type); + } catch (...) { + EVLOG_error << "Error type '" << error_type << "' is not defined, returning default description."; + description = "No description found"; + } + return description; } bool ErrorTypeMap::has(const ErrorType& error_type) const { diff --git a/lib/everest.cpp b/lib/everest.cpp index ef80e7e2..e7d37f77 100644 --- a/lib/everest.cpp +++ b/lib/everest.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -484,15 +483,17 @@ void Everest::subscribe_error(const Requirement& req, const error::ErrorType& er // split error_type at '/' int pos = error_type.find('/'); if (pos == std::string::npos) { - throw error::EverestNotValidErrorTypeError(error_type); + EVLOG_error << fmt::format("Error type {} is not valid, ignore subscription", error_type); + return; } std::string error_type_namespace = error_type.substr(0, pos); std::string error_type_name = error_type.substr(pos + 1); if (!requirement_impl_if.contains("errors") || !requirement_impl_if.at("errors").contains(error_type_namespace) || !requirement_impl_if.at("errors").at(error_type_namespace).contains(error_type_name)) { - throw error::EverestInterfaceMissingDeclartionError( - fmt::format("{}: Error {} not listed in interface!", - this->config.printable_identifier(requirement_module_id, requirement_impl_id), error_type)); + EVLOG_error << fmt::format("{}: Error {} not listed in interface, ignore subscription!", + this->config.printable_identifier(requirement_module_id, requirement_impl_id), + error_type); + return; } Handler raise_handler = [this, requirement_module_id, requirement_impl_id, error_type, callback](json const& data) { @@ -587,8 +588,9 @@ void Everest::subscribe_global_all_errors(const error::ErrorCallback& callback, EVLOG_debug << fmt::format("subscribing to all errors"); if (not this->config.get_module_info(this->module_id).global_errors_enabled) { - throw error::EverestNotAllowedError(fmt::format("Module {} is not allowed to subscribe to all errors!", - this->config.printable_identifier(this->module_id))); + EVLOG_error << fmt::format("Module {} is not allowed to subscribe to all errors, ignore subscription", + this->config.printable_identifier(this->module_id)); + return; } Handler raise_handler = [this, callback](json const& data) {