python-kasa/kasa/exceptions.py

149 lines
4.1 KiB
Python
Raw Normal View History

"""python-kasa exceptions."""
from __future__ import annotations
from asyncio import TimeoutError as _asyncioTimeoutError
from enum import IntEnum
from functools import cache
from typing import Any
class KasaException(Exception):
"""Base exception for library errors."""
class TimeoutError(KasaException, _asyncioTimeoutError):
"""Timeout exception for device errors."""
def __repr__(self):
return KasaException.__repr__(self)
def __str__(self):
return KasaException.__str__(self)
class _ConnectionError(KasaException):
"""Connection exception for device errors."""
class UnsupportedDeviceError(KasaException):
"""Exception for trying to connect to unsupported devices."""
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.discovery_result = kwargs.get("discovery_result")
super().__init__(*args)
class DeviceError(KasaException):
"""Base exception for device errors."""
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.error_code: SmartErrorCode | None = kwargs.get("error_code", None)
super().__init__(*args)
def __repr__(self):
err_code = self.error_code.__repr__() if self.error_code else ""
return f"{self.__class__.__name__}({err_code})"
def __str__(self):
err_code = f" (error_code={self.error_code.name})" if self.error_code else ""
return super().__str__() + err_code
class AuthenticationError(DeviceError):
"""Base exception for device authentication errors."""
class _RetryableError(DeviceError):
"""Retryable exception for device errors."""
class SmartErrorCode(IntEnum):
"""Enum for SMART Error Codes."""
def __str__(self):
return f"{self.name}({self.value})"
@staticmethod
@cache
def from_int(value: int) -> SmartErrorCode:
"""Convert an integer to a SmartErrorCode."""
return SmartErrorCode(value)
SUCCESS = 0
# Transport Errors
SESSION_TIMEOUT_ERROR = 9999
MULTI_REQUEST_FAILED_ERROR = 1200
HTTP_TRANSPORT_FAILED_ERROR = 1112
LOGIN_FAILED_ERROR = 1111
HAND_SHAKE_FAILED_ERROR = 1100
#: Real description unknown, seen after an encryption-changing fw upgrade
TRANSPORT_UNKNOWN_CREDENTIALS_ERROR = 1003
TRANSPORT_NOT_AVAILABLE_ERROR = 1002
CMD_COMMAND_CANCEL_ERROR = 1001
NULL_TRANSPORT_ERROR = 1000
# Common Method Errors
COMMON_FAILED_ERROR = -1
UNSPECIFIC_ERROR = -1001
UNKNOWN_METHOD_ERROR = -1002
JSON_DECODE_FAIL_ERROR = -1003
JSON_ENCODE_FAIL_ERROR = -1004
AES_DECODE_FAIL_ERROR = -1005
REQUEST_LEN_ERROR_ERROR = -1006
CLOUD_FAILED_ERROR = -1007
PARAMS_ERROR = -1008
INVALID_PUBLIC_KEY_ERROR = -1010 # Unverified
SESSION_PARAM_ERROR = -1101
# Method Specific Errors
QUICK_SETUP_ERROR = -1201
DEVICE_ERROR = -1301
DEVICE_NEXT_EVENT_ERROR = -1302
FIRMWARE_ERROR = -1401
FIRMWARE_VER_ERROR_ERROR = -1402
LOGIN_ERROR = -1501
TIME_ERROR = -1601
TIME_SYS_ERROR = -1602
TIME_SAVE_ERROR = -1603
WIRELESS_ERROR = -1701
WIRELESS_UNSUPPORTED_ERROR = -1702
SCHEDULE_ERROR = -1801
SCHEDULE_FULL_ERROR = -1802
SCHEDULE_CONFLICT_ERROR = -1803
SCHEDULE_SAVE_ERROR = -1804
SCHEDULE_INDEX_ERROR = -1805
COUNTDOWN_ERROR = -1901
COUNTDOWN_CONFLICT_ERROR = -1902
COUNTDOWN_SAVE_ERROR = -1903
ANTITHEFT_ERROR = -2001
ANTITHEFT_CONFLICT_ERROR = -2002
ANTITHEFT_SAVE_ERROR = -2003
ACCOUNT_ERROR = -2101
STAT_ERROR = -2201
STAT_SAVE_ERROR = -2202
DST_ERROR = -2301
DST_SAVE_ERROR = -2302
# Library internal for unknown error codes
INTERNAL_UNKNOWN_ERROR = -100_000
# Library internal for query errors
INTERNAL_QUERY_ERROR = -100_001
SMART_RETRYABLE_ERRORS = [
SmartErrorCode.TRANSPORT_NOT_AVAILABLE_ERROR,
SmartErrorCode.HTTP_TRANSPORT_FAILED_ERROR,
SmartErrorCode.UNSPECIFIC_ERROR,
SmartErrorCode.SESSION_TIMEOUT_ERROR,
]
SMART_AUTHENTICATION_ERRORS = [
SmartErrorCode.LOGIN_ERROR,
SmartErrorCode.LOGIN_FAILED_ERROR,
SmartErrorCode.AES_DECODE_FAIL_ERROR,
SmartErrorCode.HAND_SHAKE_FAILED_ERROR,
SmartErrorCode.TRANSPORT_UNKNOWN_CREDENTIALS_ERROR,
]