From 5afd8494ad697e00eebd0cee0c48fc1e136f7967 Mon Sep 17 00:00:00 2001 From: Emanuele Palazzetti Date: Fri, 1 Mar 2024 12:12:52 +0100 Subject: [PATCH] feat(api): handle main unit disconnections (#147) --- src/elmo/api/client.py | 11 +++++++++-- src/elmo/api/exceptions.py | 6 ++++++ tests/test_client.py | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/elmo/api/client.py b/src/elmo/api/client.py index 444f5d4..3aa0468 100644 --- a/src/elmo/api/client.py +++ b/src/elmo/api/client.py @@ -15,6 +15,7 @@ CodeError, CommandError, CredentialError, + DeviceDisconnectedError, InvalidToken, LockError, ParseError, @@ -622,8 +623,14 @@ def query(self, query): # Bail-out if the query is not recognized raise QueryNotValid() - response = self._session.post(endpoint, data={"sessionId": self._session_id}) - response.raise_for_status() + try: + response = self._session.post(endpoint, data={"sessionId": self._session_id}) + response.raise_for_status() + except HTTPError as err: + # Handle the case when the device is disconnected + if err.response.status_code == 403 and "Centrale non connessa" in err.response.text: + raise DeviceDisconnectedError + raise err if query in [q.SECTORS, q.INPUTS, q.OUTPUTS]: # Retrieve description or use the cache diff --git a/src/elmo/api/exceptions.py b/src/elmo/api/exceptions.py index 6630e8b..05a6924 100644 --- a/src/elmo/api/exceptions.py +++ b/src/elmo/api/exceptions.py @@ -74,3 +74,9 @@ class CommandError(APIException): """Exception raised when the API returns an error response after issuing a command.""" default_message = "An error occurred while executing the command." + + +class DeviceDisconnectedError(APIException): + """Exception raised when the device is disconnected.""" + + default_message = "Unable to execute commands. Device is disconnected." diff --git a/tests/test_client.py b/tests/test_client.py index 0087dca..e5ead53 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -10,6 +10,7 @@ CodeError, CommandError, CredentialError, + DeviceDisconnectedError, InvalidToken, LockError, LockNotAcquired, @@ -2414,6 +2415,22 @@ def test_client_query_invalid_response(server, mocker): client.query(query.SECTORS) +def test_client_query_unit_disconnected(server, mocker): + # Ensure that the client catches and raises an exception when the unit is disconnected + server.add( + responses.POST, + "https://example.com/api/areas", + body='"Centrale non connessa"', + status=403, + ) + client = ElmoClient(base_url="https://example.com", domain="domain") + client._session_id = "test" + mocker.patch.object(client, "_get_descriptions") + # Test + with pytest.raises(DeviceDisconnectedError): + client.query(query.SECTORS) + + def test_client_get_alerts_status(server): """Should query a Elmo system to retrieve alerts status.""" html = """