"""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) -> str: return KasaException.__repr__(self) def __str__(self) -> str: 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") self.host = kwargs.get("host") 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") super().__init__(*args) def __repr__(self) -> str: err_code = self.error_code.__repr__() if self.error_code else "" return f"{self.__class__.__name__}({err_code})" def __str__(self) -> str: 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) -> str: 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 SYSTEM_ERROR = -40101 INVALID_ARGUMENTS = -40209 # Camera error codes SESSION_EXPIRED = -40401 HOMEKIT_LOGIN_FAIL = -40412 DEVICE_BLOCKED = -40404 DEVICE_FACTORY = -40405 OUT_OF_LIMIT = -40406 OTHER_ERROR = -40407 SYSTEM_BLOCKED = -40408 NONCE_EXPIRED = -40409 FFS_NONE_PWD = -90000 TIMEOUT_ERROR = 40108 UNSUPPORTED_METHOD = -40106 ONE_SECOND_REPEAT_REQUEST = -40109 INVALID_NONCE = -40413 PROTOCOL_FORMAT_ERROR = -40210 IP_CONFLICT = -40321 DIAGNOSE_TYPE_NOT_SUPPORT = -69051 DIAGNOSE_TASK_FULL = -69052 DIAGNOSE_TASK_BUSY = -69053 DIAGNOSE_INTERNAL_ERROR = -69055 DIAGNOSE_ID_NOT_FOUND = -69056 DIAGNOSE_TASK_NULL = -69057 CLOUD_LINK_DOWN = -69060 ONVIF_SET_WRONG_TIME = -69061 CLOUD_NTP_NO_RESPONSE = -69062 CLOUD_GET_WRONG_TIME = -69063 SNTP_SRV_NO_RESPONSE = -69064 SNTP_GET_WRONG_TIME = -69065 LINK_UNCONNECTED = -69076 WIFI_SIGNAL_WEAK = -69077 LOCAL_NETWORK_POOR = -69078 CLOUD_NETWORK_POOR = -69079 INTER_NETWORK_POOR = -69080 DNS_TIMEOUT = -69081 DNS_ERROR = -69082 PING_NO_RESPONSE = -69083 DHCP_MULTI_SERVER = -69084 DHCP_ERROR = -69085 STREAM_SESSION_CLOSE = -69094 STREAM_BITRATE_EXCEPTION = -69095 STREAM_FULL = -69096 STREAM_NO_INTERNET = -69097 HARDWIRED_NOT_FOUND = -72101 # 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, SmartErrorCode.SESSION_EXPIRED, SmartErrorCode.INVALID_NONCE, ] 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, SmartErrorCode.HOMEKIT_LOGIN_FAIL, ]