palazzem / econnect-python

API adapter used to control programmatically an Elmo alarm system
BSD 3-Clause "New" or "Revised" License
8 stars 5 forks source link

Handle main unit disconnections #146

Closed palazzem closed 7 months ago

palazzem commented 7 months ago

Is your feature request related to a problem? Please describe. When the main unit is disconnected, HTTPError exceptions are raised, causing the caller to fail without knowing what the underlying issue is.

Describe the solution you'd like The library should raise DeviceDisconnectedError if the main unit is disconnected. In this way, the caller can handle the exception and decide what to do.

Describe alternatives you've considered n/a

Additional context n/a

palazzem commented 7 months ago

When the main unit is disconnected, calling client.query(query.SECTORS) raises the following exception:

In [31]: client.query(query.SECTORS)
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
Cell In[31], line 1
----> 1 client.query(query.SECTORS)

File ~/workspaces/econnect-python/src/elmo/api/decorators.py:28, in require_session.<locals>.func_wrapper(*args, **kwargs)
     26 if e.response.status_code == 401:
     27     raise InvalidToken
---> 28 raise e

File ~/workspaces/econnect-python/src/elmo/api/decorators.py:22, in require_session.<locals>.func_wrapper(*args, **kwargs)
     20 else:
     21     try:
---> 22         return func(*args, **kwargs)
     23     except HTTPError as e:
     24         # Translate 401 into InvalidToken exception
     25         # Bubble up any other exception
     26         if e.response.status_code == 401:

File ~/workspaces/econnect-python/src/elmo/api/client.py:626, in ElmoClient.query(self, query)
    623     raise QueryNotValid()
    625 response = self._session.post(endpoint, data={"sessionId": self._session_id})
--> 626 response.raise_for_status()
    628 if query in [q.SECTORS, q.INPUTS, q.OUTPUTS]:
    629     # Retrieve description or use the cache
    630     descriptions = self._get_descriptions()

File ~/workspaces/econnect-python/venv/lib/python3.11/site-packages/requests/models.py:1021, in Response.raise_for_status(self)
   1016     http_error_msg = (
   1017         f"{self.status_code} Server Error: {reason} for url: {self.url}"
   1018     )
   1020 if http_error_msg:
-> 1021     raise HTTPError(http_error_msg, response=self)

HTTPError: 403 Client Error: Forbidden for url: https://connect.elmospa.com/api/areas

To handle the client.query() call we should:

Once this is done, we should check other APIs (e.g. client.poll()).

palazzem commented 7 months ago

client.poll() doesn't return an error if the main unit is disconnected. For that reason, it's enough to cover the query() call.