Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve exceptions making them more user friendly #237

Merged
merged 1 commit into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions pyrainbird/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,16 @@ async def request(
except ClientResponseError as err:
if err.status == HTTPStatus.SERVICE_UNAVAILABLE:
raise RainbirdDeviceBusyException(
"Device is busy; Wait 1 minute"
"Rain Bird device is busy; Wait and try again"
) from err
if err.status == HTTPStatus.FORBIDDEN:
raise RainbirdAuthException(
f"Error authenticating with Device: {err}"
"Rain Bird device denied authentication; Incorrect Password?"
) from err
raise RainbirdApiException(f"Error from API: {str(err)}") from err
raise RainbirdApiException("Rain Bird responded with an error")
except ClientError as err:
raise RainbirdApiException(
f"Error communicating with device: {str(err)}"
"Error communicating with Rain Bird device"
) from err
content = await resp.read()
return self._coder.decode_command(content)
Expand Down Expand Up @@ -469,7 +469,10 @@ async def _tunnelSip(self, data: str, length: int) -> str:
"tunnelSip", {DATA: data, LENGTH: length}
)
if DATA not in result:
raise RainbirdApiException("Missing 'data' in tunnelSip response")
_LOGGER.error(
"Rain Bird device reply missing required 'data' field in tunnelSip"
)
raise RainbirdApiException("Unexpected response from Rain Bird device")
return result[DATA]

async def _process_command(
Expand All @@ -490,10 +493,11 @@ async def _process_command(
if funct is None:
allowed.add("00") # Allow NACK
if response_code not in allowed:
raise RainbirdApiException(
_LOGGER.error(
"Request (%s) failed with wrong response! Requested (%s), got %s:\n%s"
% (command, allowed, response_code, decoded)
)
raise RainbirdApiException("Unexpected response from Rain Bird device")
return funct(decoded) if funct is not None else decoded

async def _cacheable_command(
Expand Down
4 changes: 3 additions & 1 deletion pyrainbird/encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from .exceptions import RainbirdApiException


BLOCK_SIZE = 16
INTERRUPT = "\x00"
PAD = "\x10"
Expand Down Expand Up @@ -124,5 +125,6 @@ def decode_command(self, content: bytes) -> str:
if message := error.get("message"):
msg.append(f"Message: {message}")
", ".join(msg)
raise RainbirdApiException(", ".join(msg))
self._logger.debug("Error from controller: %s", msg)
raise RainbirdApiException(f"Rain Bird responded with an error: {message}")
return response["result"]
4 changes: 2 additions & 2 deletions pyrainbird/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ class RainbirdAuthException(RainbirdApiException):
"""Authentication exception from rainbird API."""


class RainbirdCodingException(RainbirdApiException):
"""Error while encoding or decoding objects."""
class RainbirdCodingException(Exception):
"""Error while encoding or decoding objects indicating a bug."""
4 changes: 3 additions & 1 deletion tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,9 @@ async def test_unrecognized_response(
"id": 0,
}
encrypt_response(payload)
with pytest.raises(RainbirdApiException, match=r"wrong response"):
with pytest.raises(
RainbirdApiException, match=r"Unexpected response from Rain Bird device"
):
await controller.test_command_support("00")


Expand Down