diff --git a/include/ocpp/v201/component_state_manager.hpp b/include/ocpp/v201/component_state_manager.hpp index 2f227a55d..32e7ba9a9 100644 --- a/include/ocpp/v201/component_state_manager.hpp +++ b/include/ocpp/v201/component_state_manager.hpp @@ -8,6 +8,40 @@ namespace ocpp::v201 { +/// \brief Exception used when an evse that does not exist is accessed. +class EvseOutOfRangeException : public std::exception { +public: + explicit EvseOutOfRangeException(int32_t id) : msg{"Evse with id " + std::to_string(id) + " does not exist"} { + } + + ~EvseOutOfRangeException() noexcept override = default; + + const char* what() const noexcept override { + return msg.c_str(); + } + +private: + std::string msg; +}; + +/// \brief Exception used when an connector_id that does not exist is accessed. +class ConnectorOutOfRangeException : public std::exception { +public: + explicit ConnectorOutOfRangeException(int32_t connector_id, int32_t evse_id) : + msg{"Connector with id " + std::to_string(connector_id) + " does not exist for evse with id " + + std::to_string(evse_id)} { + } + + ~ConnectorOutOfRangeException() noexcept override = default; + + const char* what() const noexcept override { + return msg.c_str(); + } + +private: + std::string msg; +}; + /// \brief Describes the individual state of a single connector struct FullConnectorStatus { /// \brief Operative/Inoperative status, usually set by the CSMS diff --git a/include/ocpp/v201/evse_manager.hpp b/include/ocpp/v201/evse_manager.hpp index cbe620187..f2da7ba88 100644 --- a/include/ocpp/v201/evse_manager.hpp +++ b/include/ocpp/v201/evse_manager.hpp @@ -9,22 +9,6 @@ namespace ocpp { namespace v201 { -/// \brief Exception used when an evse that does not exist is accessed. -class EvseOutOfRangeException : public std::exception { -public: - explicit EvseOutOfRangeException(int32_t id) : msg{"Evse with id " + std::to_string(id) + " does not exist"} { - } - - ~EvseOutOfRangeException() noexcept override = default; - - const char* what() const noexcept override { - return msg.c_str(); - } - -private: - std::string msg; -}; - /// \brief Class used to access the Evse instances class EvseManagerInterface { public: diff --git a/lib/ocpp/v201/charge_point.cpp b/lib/ocpp/v201/charge_point.cpp index c9920692d..b8a2f66ee 100644 --- a/lib/ocpp/v201/charge_point.cpp +++ b/lib/ocpp/v201/charge_point.cpp @@ -1476,6 +1476,10 @@ void ChargePoint::message_callback(const std::string& message) { EVLOG_error << "Exception during handling of message: " << e.what(); auto call_error = CallError(enhanced_message.uniqueId, "OccurrenceConstraintViolation", e.what(), json({})); this->send(call_error); + } catch (const ConnectorOutOfRangeException& e) { + EVLOG_error << "Exception during handling of message: " << e.what(); + auto call_error = CallError(enhanced_message.uniqueId, "OccurrenceConstraintViolation", e.what(), json({})); + this->send(call_error); } catch (const EnumConversionException& e) { EVLOG_error << "EnumConversionException during handling of message: " << e.what(); auto call_error = CallError(enhanced_message.uniqueId, "FormationViolation", e.what(), json({})); diff --git a/lib/ocpp/v201/component_state_manager.cpp b/lib/ocpp/v201/component_state_manager.cpp index ac057d465..25cf9b2ac 100644 --- a/lib/ocpp/v201/component_state_manager.cpp +++ b/lib/ocpp/v201/component_state_manager.cpp @@ -80,9 +80,7 @@ int32_t ComponentStateManager::num_evses() { void ComponentStateManager::check_evse_id(int32_t evse_id) { if (evse_id <= 0 || evse_id > this->num_evses()) { - std::stringstream errmsg; - errmsg << "EVSE ID " << evse_id << " out of bounds."; - throw std::out_of_range(errmsg.str()); + throw EvseOutOfRangeException(evse_id); } } @@ -94,9 +92,7 @@ int32_t ComponentStateManager::num_connectors(int32_t evse_id) { void ComponentStateManager::check_evse_and_connector_id(int32_t evse_id, int32_t connector_id) { this->check_evse_id(evse_id); if (connector_id <= 0 || connector_id > this->num_connectors(evse_id)) { - std::stringstream errmsg; - errmsg << "Connector ID " << connector_id << "out of bounds for EVSE ID " << evse_id << "."; - throw std::out_of_range(errmsg.str()); + throw ConnectorOutOfRangeException(connector_id, evse_id); } } diff --git a/tests/lib/ocpp/v201/test_component_state_manager.cpp b/tests/lib/ocpp/v201/test_component_state_manager.cpp index f8b4cda51..533b01d9f 100644 --- a/tests/lib/ocpp/v201/test_component_state_manager.cpp +++ b/tests/lib/ocpp/v201/test_component_state_manager.cpp @@ -148,18 +148,18 @@ TEST_F(ComponentStateManagerTest, test_check_evse_and_connector_ids) { auto state_mgr = this->component_state_manager(mock_database, {1, 2}); // Act & Verify - ASSERT_THROW(state_mgr.get_evse_effective_operational_status(0), std::out_of_range); - ASSERT_THROW(state_mgr.get_evse_effective_operational_status(-1), std::out_of_range); - ASSERT_THROW(state_mgr.get_evse_effective_operational_status(3), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(0, 1), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(-1, 1), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(3, 1), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(1, -1), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(1, 0), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(1, 2), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(2, -1), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(2, 0), std::out_of_range); - ASSERT_THROW(state_mgr.get_connector_effective_operational_status(2, 3), std::out_of_range); + ASSERT_THROW(state_mgr.get_evse_effective_operational_status(0), EvseOutOfRangeException); + ASSERT_THROW(state_mgr.get_evse_effective_operational_status(-1), EvseOutOfRangeException); + ASSERT_THROW(state_mgr.get_evse_effective_operational_status(3), EvseOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(0, 1), EvseOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(-1, 1), EvseOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(3, 1), EvseOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(1, -1), ConnectorOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(1, 0), ConnectorOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(1, 2), ConnectorOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(2, -1), ConnectorOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(2, 0), ConnectorOutOfRangeException); + ASSERT_THROW(state_mgr.get_connector_effective_operational_status(2, 3), ConnectorOutOfRangeException); } /// \brief Test that the ComponentStateManager assumes missing states are Operative