1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
"""Module for common types (exceptions, enums)."""
from enum import Enum, IntEnum
from typing import Optional
class DeviceErrorCode(IntEnum):
"""Error code mapping.
https://developer.sony.com/develop/audio-control-api/api-references/error-codes
"""
Unknown = -1
Generic = 1
Timeout = 2
IllegalArgument = 3
IllegalRequest = 5
IllegalState = 7
NoSuchMethod = 12
UnsupportedVersion = 14
UnsupportedOperation = 15
class DeviceError:
"""Container for device-given errors."""
def __init__(self, error):
self.error_code, self.error_message = error
@property
def error(self):
"""Return user-friendly error message."""
try:
errcode = DeviceErrorCode(self.error_code)
return f"{errcode.name} ({errcode.value}): {self.error_message}"
except: # noqa: E722
return f"Unknown error {self.error_code}: {self.error_message}"
def __str__(self):
return self.error
class SongpalException(Exception):
"""Custom exception class.
This is used to wrap exceptions coming from this lib.
In case of an error from the endpoint device, the delivered error code
and the corresponding message is stored in `code` and `message` variables
accordingly.
"""
def __init__(self, message, *, error=None):
"""Overridden __init__ to allow passing an extra error message.
This is used to pass the raw error message from the device.
"""
super().__init__(message)
self.message = message
self._error = None
if error is not None:
self._error = DeviceError(error)
@property
def error(self) -> Optional[DeviceError]:
"""Return a pretty error for device-returned error."""
return self._error
@property
def code(self) -> Optional[int]:
"""Return device-given error code."""
if self.error is not None:
return self.error.error_code
return None
@property
def error_message(self) -> Optional[str]:
"""Return device-given error message."""
if self._error is not None:
return self._error.error_message
return None
def __str__(self):
return f"{self.message}: {str(self.error)}"
class ProtocolType(Enum):
"""Protocol used for communication."""
WebSocket = "websocket:jsonizer"
XHRPost = "xhrpost:jsonizer"
|