| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4beff22 commit 8c39e81
44 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,12 +22,12 @@ | |||
| 22 | 22 | ||
| 23 | 23 | from devtools.helpers.smartrequests import SmartRequest, get_component_requests | |
| 24 | 24 | from kasa import ( | |
| 25 | - AuthenticationException, | ||
| 25 | + AuthenticationError, | ||
| 26 | 26 | Credentials, | |
| 27 | 27 | Device, | |
| 28 | 28 | Discover, | |
| 29 | - SmartDeviceException, | ||
| 30 | - TimeoutException, | ||
| 29 | + KasaException, | ||
| 30 | + TimeoutError, | ||
| 31 | 31 | ) | |
| 32 | 32 | from kasa.discover import DiscoveryResult | |
| 33 | 33 | from kasa.exceptions import SmartErrorCode | |
@@ -303,19 +303,16 @@ async def _make_requests_or_exit( | |||
| 303 | 303 | for method, result in responses.items(): | |
| 304 | 304 | final[method] = result | |
| 305 | 305 | return final | |
| 306 | - except AuthenticationException as ex: | ||
| 306 | + except AuthenticationError as ex: | ||
| 307 | 307 | _echo_error( | |
| 308 | 308 | f"Unable to query the device due to an authentication error: {ex}", | |
| 309 | 309 | ) | |
| 310 | 310 | exit(1) | |
| 311 | - except SmartDeviceException as ex: | ||
| 311 | + except KasaException as ex: | ||
| 312 | 312 | _echo_error( | |
| 313 | 313 | f"Unable to query {name} at once: {ex}", | |
| 314 | 314 | ) | |
| 315 | - if ( | ||
| 316 | - isinstance(ex, TimeoutException) | ||
| 317 | - or ex.error_code == SmartErrorCode.SESSION_TIMEOUT_ERROR | ||
| 318 | - ): | ||
| 315 | + if isinstance(ex, TimeoutError): | ||
| 319 | 316 | _echo_error( | |
| 320 | 317 | "Timeout, try reducing the batch size via --batch-size option.", | |
| 321 | 318 | ) | |
@@ -400,7 +397,7 @@ async def get_smart_fixture(device: SmartDevice, batch_size: int): | |||
| 400 | 397 | response = await device.protocol.query( | |
| 401 | 398 | SmartRequest._create_request_dict(test_call.request) | |
| 402 | 399 | ) | |
| 403 | - except AuthenticationException as ex: | ||
| 400 | + except AuthenticationError as ex: | ||
| 404 | 401 | _echo_error( | |
| 405 | 402 | f"Unable to query the device due to an authentication error: {ex}", | |
| 406 | 403 | ) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -100,6 +100,17 @@ The classes providing this functionality are: | |||
| 100 | 100 | - :class:`KlapTransport <kasa.klaptransport.KlapTransport>` | |
| 101 | 101 | - :class:`KlapTransportV2 <kasa.klaptransport.KlapTransportV2>` | |
| 102 | 102 | ||
| 103 | + Errors and Exceptions | ||
| 104 | + ********************* | ||
| 105 | + | ||
| 106 | + The base exception for all library errors is :class:`KasaException <kasa.exceptions.KasaException>`. | ||
| 107 | + | ||
| 108 | + - If the device returns an error the library raises a :class:`DeviceError <kasa.exceptions.DeviceError>` which will usually contain an ``error_code`` with the detail. | ||
| 109 | + - If the device fails to authenticate the library raises an :class:`AuthenticationError <kasa.exceptions.AuthenticationError>` which is derived | ||
| 110 | + from :class:`DeviceError <kasa.exceptions.DeviceError>` and could contain an ``error_code`` depending on the type of failure. | ||
| 111 | + - If the library encounters and unsupported deviceit raises an :class:`UnsupportedDeviceError <kasa.exceptions.UnsupportedDeviceError>`. | ||
| 112 | + - If the device fails to respond within a timeout the library raises a :class:`TimeoutError <kasa.exceptions.TimeoutError>`. | ||
| 113 | + - All other failures will raise the base :class:`KasaException <kasa.exceptions.KasaException>` class. | ||
| 103 | 114 | ||
| 104 | 115 | API documentation for modules | |
| 105 | 116 | ***************************** | |
@@ -154,3 +165,26 @@ API documentation for protocols and transports | |||
| 154 | 165 | :members: | |
| 155 | 166 | :inherited-members: | |
| 156 | 167 | :undoc-members: | |
| 168 | + | ||
| 169 | + API documentation for errors and exceptions | ||
| 170 | + ******************************************* | ||
| 171 | + | ||
| 172 | + .. autoclass:: kasa.exceptions.KasaException | ||
| 173 | + :members: | ||
| 174 | + :undoc-members: | ||
| 175 | + | ||
| 176 | + .. autoclass:: kasa.exceptions.DeviceError | ||
| 177 | + :members: | ||
| 178 | + :undoc-members: | ||
| 179 | + | ||
| 180 | + .. autoclass:: kasa.exceptions.AuthenticationError | ||
| 181 | + :members: | ||
| 182 | + :undoc-members: | ||
| 183 | + | ||
| 184 | + .. autoclass:: kasa.exceptions.UnsupportedDeviceError | ||
| 185 | + :members: | ||
| 186 | + :undoc-members: | ||
| 187 | + | ||
| 188 | + .. autoclass:: kasa.exceptions.TimeoutError | ||
| 189 | + :members: | ||
| 190 | + :undoc-members: | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,7 @@ Methods changing the state of the device do not invalidate the cache (i.e., ther | |||
| 24 | 24 | You can assume that the operation has succeeded if no exception is raised. | |
| 25 | 25 | These methods will return the device response, which can be useful for some use cases. | |
| 26 | 26 | ||
| 27 | - Errors are raised as :class:`SmartDeviceException` instances for the library user to handle. | ||
| 27 | + Errors are raised as :class:`KasaException` instances for the library user to handle. | ||
| 28 | 28 | ||
| 29 | 29 | Simple example script showing some functionality for legacy devices: | |
| 30 | 30 | ||
@@ -154,15 +154,3 @@ API documentation | |||
| 154 | 154 | .. autoclass:: Credentials | |
| 155 | 155 | :members: | |
| 156 | 156 | :undoc-members: | |
| 157 | - | ||
| 158 | - .. autoclass:: SmartDeviceException | ||
| 159 | - :members: | ||
| 160 | - :undoc-members: | ||
| 161 | - | ||
| 162 | - .. autoclass:: AuthenticationException | ||
| 163 | - :members: | ||
| 164 | - :undoc-members: | ||
| 165 | - | ||
| 166 | - .. autoclass:: UnsupportedDeviceException | ||
| 167 | - :members: | ||
| 168 | - :undoc-members: | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,7 +8,7 @@ | |||
| 8 | 8 | For device type specific actions `SmartBulb`, `SmartPlug`, or `SmartStrip` | |
| 9 | 9 | should be used instead. | |
| 10 | 10 | ||
| 11 | - Module-specific errors are raised as `SmartDeviceException` and are expected | ||
| 11 | + Module-specific errors are raised as `KasaException` and are expected | ||
| 12 | 12 | to be handled by the user of the library. | |
| 13 | 13 | """ | |
| 14 | 14 | from importlib.metadata import version | |
@@ -28,10 +28,11 @@ | |||
| 28 | 28 | from kasa.discover import Discover | |
| 29 | 29 | from kasa.emeterstatus import EmeterStatus | |
| 30 | 30 | from kasa.exceptions import ( | |
| 31 | - AuthenticationException, | ||
| 32 | - SmartDeviceException, | ||
| 33 | - TimeoutException, | ||
| 34 | - UnsupportedDeviceException, | ||
| 31 | + AuthenticationError, | ||
| 32 | + DeviceError, | ||
| 33 | + KasaException, | ||
| 34 | + TimeoutError, | ||
| 35 | + UnsupportedDeviceError, | ||
| 35 | 36 | ) | |
| 36 | 37 | from kasa.feature import Feature, FeatureType | |
| 37 | 38 | from kasa.iot.iotbulb import BulbPreset, TurnOnBehavior, TurnOnBehaviors | |
@@ -61,10 +62,11 @@ | |||
| 61 | 62 | "Device", | |
| 62 | 63 | "Bulb", | |
| 63 | 64 | "Plug", | |
| 64 | - "SmartDeviceException", | ||
| 65 | - "AuthenticationException", | ||
| 66 | - "UnsupportedDeviceException", | ||
| 67 | - "TimeoutException", | ||
| 65 | + "KasaException", | ||
| 66 | + "AuthenticationError", | ||
| 67 | + "DeviceError", | ||
| 68 | + "UnsupportedDeviceError", | ||
| 69 | + "TimeoutError", | ||
| 68 | 70 | "Credentials", | |
| 69 | 71 | "DeviceConfig", | |
| 70 | 72 | "ConnectionType", | |
@@ -84,6 +86,12 @@ | |||
| 84 | 86 | "SmartDimmer": iot.IotDimmer, | |
| 85 | 87 | "SmartBulbPreset": BulbPreset, | |
| 86 | 88 | } | |
| 89 | + deprecated_exceptions = { | ||
| 90 | + "SmartDeviceException": KasaException, | ||
| 91 | + "UnsupportedDeviceException": UnsupportedDeviceError, | ||
| 92 | + "AuthenticationException": AuthenticationError, | ||
| 93 | + "TimeoutException": TimeoutError, | ||
| 94 | + } | ||
| 87 | 95 | ||
| 88 | 96 | ||
| 89 | 97 | def __getattr__(name): | |
@@ -101,6 +109,11 @@ def __getattr__(name): | |||
| 101 | 109 | stacklevel=1, | |
| 102 | 110 | ) | |
| 103 | 111 | return new_class | |
| 112 | + if name in deprecated_exceptions: | ||
| 113 | + new_class = deprecated_exceptions[name] | ||
| 114 | + msg = f"{name} is deprecated, use {new_class.__name__} instead" | ||
| 115 | + warn(msg, DeprecationWarning, stacklevel=1) | ||
| 116 | + return new_class | ||
| 104 | 117 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") | |
| 105 | 118 | ||
| 106 | 119 | ||
@@ -112,6 +125,11 @@ def __getattr__(name): | |||
| 112 | 125 | SmartStrip = iot.IotStrip | |
| 113 | 126 | SmartDimmer = iot.IotDimmer | |
| 114 | 127 | SmartBulbPreset = BulbPreset | |
| 128 | + | ||
| 129 | + SmartDeviceException = KasaException | ||
| 130 | + UnsupportedDeviceException = UnsupportedDeviceError | ||
| 131 | + AuthenticationException = AuthenticationError | ||
| 132 | + TimeoutException = TimeoutError | ||
| 115 | 133 | # Instanstiate all classes so the type checkers catch abstract issues | |
| 116 | 134 | from . import smart | |
| 117 | 135 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,12 +22,11 @@ | |||
| 22 | 22 | from .exceptions import ( | |
| 23 | 23 | SMART_AUTHENTICATION_ERRORS, | |
| 24 | 24 | SMART_RETRYABLE_ERRORS, | |
| 25 | - SMART_TIMEOUT_ERRORS, | ||
| 26 | - AuthenticationException, | ||
| 27 | - RetryableException, | ||
| 28 | - SmartDeviceException, | ||
| 25 | + AuthenticationError, | ||
| 26 | + DeviceError, | ||
| 27 | + KasaException, | ||
| 29 | 28 | SmartErrorCode, | |
| 30 | - TimeoutException, | ||
| 29 | + _RetryableError, | ||
| 31 | 30 | ) | |
| 32 | 31 | from .httpclient import HttpClient | |
| 33 | 32 | from .json import dumps as json_dumps | |
@@ -141,14 +140,12 @@ def _handle_response_error_code(self, resp_dict: Any, msg: str) -> None: | |||
| 141 | 140 | if error_code == SmartErrorCode.SUCCESS: | |
| 142 | 141 | return | |
| 143 | 142 | msg = f"{msg}: {self._host}: {error_code.name}({error_code.value})" | |
| 144 | - if error_code in SMART_TIMEOUT_ERRORS: | ||
| 145 | - raise TimeoutException(msg, error_code=error_code) | ||
| 146 | 143 | if error_code in SMART_RETRYABLE_ERRORS: | |
| 147 | - raise RetryableException(msg, error_code=error_code) | ||
| 144 | + raise _RetryableError(msg, error_code=error_code) | ||
| 148 | 145 | if error_code in SMART_AUTHENTICATION_ERRORS: | |
| 149 | 146 | self._state = TransportState.HANDSHAKE_REQUIRED | |
| 150 | - raise AuthenticationException(msg, error_code=error_code) | ||
| 151 | - raise SmartDeviceException(msg, error_code=error_code) | ||
| 147 | + raise AuthenticationError(msg, error_code=error_code) | ||
| 148 | + raise DeviceError(msg, error_code=error_code) | ||
| 152 | 149 | ||
| 153 | 150 | async def send_secure_passthrough(self, request: str) -> Dict[str, Any]: | |
| 154 | 151 | """Send encrypted message as passthrough.""" | |
@@ -171,7 +168,7 @@ async def send_secure_passthrough(self, request: str) -> Dict[str, Any]: | |||
| 171 | 168 | # _LOGGER.debug(f"secure_passthrough response is {status_code}: {resp_dict}") | |
| 172 | 169 | ||
| 173 | 170 | if status_code != 200: | |
| 174 | - raise SmartDeviceException( | ||
| 171 | + raise KasaException( | ||
| 175 | 172 | f"{self._host} responded with an unexpected " | |
| 176 | 173 | + f"status code {status_code} to passthrough" | |
| 177 | 174 | ) | |
@@ -197,7 +194,7 @@ async def send_secure_passthrough(self, request: str) -> Dict[str, Any]: | |||
| 197 | 194 | self._host, | |
| 198 | 195 | ) | |
| 199 | 196 | except Exception: | |
| 200 | - raise SmartDeviceException( | ||
| 197 | + raise KasaException( | ||
| 201 | 198 | f"Unable to decrypt response from {self._host}, " | |
| 202 | 199 | + f"error: {ex}, response: {raw_response}", | |
| 203 | 200 | ex, | |
@@ -208,7 +205,7 @@ async def perform_login(self): | |||
| 208 | 205 | """Login to the device.""" | |
| 209 | 206 | try: | |
| 210 | 207 | await self.try_login(self._login_params) | |
| 211 | - except AuthenticationException as aex: | ||
| 208 | + except AuthenticationError as aex: | ||
| 212 | 209 | try: | |
| 213 | 210 | if aex.error_code is not SmartErrorCode.LOGIN_ERROR: | |
| 214 | 211 | raise aex | |
@@ -223,10 +220,10 @@ async def perform_login(self): | |||
| 223 | 220 | "%s: logged in with default credentials", | |
| 224 | 221 | self._host, | |
| 225 | 222 | ) | |
| 226 | - except AuthenticationException: | ||
| 223 | + except AuthenticationError: | ||
| 227 | 224 | raise | |
| 228 | 225 | except Exception as ex: | |
| 229 | - raise SmartDeviceException( | ||
| 226 | + raise KasaException( | ||
| 230 | 227 | "Unable to login and trying default " | |
| 231 | 228 | + f"login raised another exception: {ex}", | |
| 232 | 229 | ex, | |
@@ -292,7 +289,7 @@ async def perform_handshake(self) -> None: | |||
| 292 | 289 | _LOGGER.debug("Device responded with: %s", resp_dict) | |
| 293 | 290 | ||
| 294 | 291 | if status_code != 200: | |
| 295 | - raise SmartDeviceException( | ||
| 292 | + raise KasaException( | ||
| 296 | 293 | f"{self._host} responded with an unexpected " | |
| 297 | 294 | + f"status code {status_code} to handshake" | |
| 298 | 295 | ) | |
@@ -347,7 +344,7 @@ async def send(self, request: str) -> Dict[str, Any]: | |||
| 347 | 344 | await self.perform_login() | |
| 348 | 345 | # After a login failure handshake needs to | |
| 349 | 346 | # be redone or a 9999 error is received. | |
| 350 | - except AuthenticationException as ex: | ||
| 347 | + except AuthenticationError as ex: | ||
| 351 | 348 | self._state = TransportState.HANDSHAKE_REQUIRED | |
| 352 | 349 | raise ex | |
| 353 | 350 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,7 +13,7 @@ | |||
| 13 | 13 | import asyncclick as click | |
| 14 | 14 | ||
| 15 | 15 | from kasa import ( | |
| 16 | - AuthenticationException, | ||
| 16 | + AuthenticationError, | ||
| 17 | 17 | Bulb, | |
| 18 | 18 | ConnectionType, | |
| 19 | 19 | Credentials, | |
@@ -22,8 +22,8 @@ | |||
| 22 | 22 | DeviceFamilyType, | |
| 23 | 23 | Discover, | |
| 24 | 24 | EncryptType, | |
| 25 | - SmartDeviceException, | ||
| 26 | - UnsupportedDeviceException, | ||
| 25 | + KasaException, | ||
| 26 | + UnsupportedDeviceError, | ||
| 27 | 27 | ) | |
| 28 | 28 | from kasa.discover import DiscoveryResult | |
| 29 | 29 | from kasa.iot import IotBulb, IotDevice, IotDimmer, IotLightStrip, IotPlug, IotStrip | |
@@ -458,7 +458,7 @@ async def discover(ctx): | |||
| 458 | 458 | unsupported = [] | |
| 459 | 459 | auth_failed = [] | |
| 460 | 460 | ||
| 461 | - async def print_unsupported(unsupported_exception: UnsupportedDeviceException): | ||
| 461 | + async def print_unsupported(unsupported_exception: UnsupportedDeviceError): | ||
| 462 | 462 | unsupported.append(unsupported_exception) | |
| 463 | 463 | async with sem: | |
| 464 | 464 | if unsupported_exception.discovery_result: | |
@@ -476,7 +476,7 @@ async def print_discovered(dev: Device): | |||
| 476 | 476 | async with sem: | |
| 477 | 477 | try: | |
| 478 | 478 | await dev.update() | |
| 479 | - except AuthenticationException: | ||
| 479 | + except AuthenticationError: | ||
| 480 | 480 | auth_failed.append(dev._discovery_info) | |
| 481 | 481 | echo("== Authentication failed for device ==") | |
| 482 | 482 | _echo_discovery_info(dev._discovery_info) | |
@@ -677,7 +677,7 @@ async def cmd_command(dev: Device, module, command, parameters): | |||
| 677 | 677 | elif isinstance(dev, SmartDevice): | |
| 678 | 678 | res = await dev._query_helper(command, parameters) | |
| 679 | 679 | else: | |
| 680 | - raise SmartDeviceException("Unexpected device type %s.", dev) | ||
| 680 | + raise KasaException("Unexpected device type %s.", dev) | ||
| 681 | 681 | echo(json.dumps(res)) | |
| 682 | 682 | return res | |
| 683 | 683 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,7 +9,7 @@ | |||
| 9 | 9 | from .device_type import DeviceType | |
| 10 | 10 | from .deviceconfig import DeviceConfig | |
| 11 | 11 | from .emeterstatus import EmeterStatus | |
| 12 | - from .exceptions import SmartDeviceException | ||
| 12 | + from .exceptions import KasaException | ||
| 13 | 13 | from .feature import Feature | |
| 14 | 14 | from .iotprotocol import IotProtocol | |
| 15 | 15 | from .protocol import BaseProtocol | |
@@ -242,12 +242,12 @@ def get_plug_by_name(self, name: str) -> "Device": | |||
| 242 | 242 | if p.alias == name: | |
| 243 | 243 | return p | |
| 244 | 244 | ||
| 245 | - raise SmartDeviceException(f"Device has no child with {name}") | ||
| 245 | + raise KasaException(f"Device has no child with {name}") | ||
| 246 | 246 | ||
| 247 | 247 | def get_plug_by_index(self, index: int) -> "Device": | |
| 248 | 248 | """Return child device for the given index.""" | |
| 249 | 249 | if index + 1 > len(self.children) or index < 0: | |
| 250 | - raise SmartDeviceException( | ||
| 250 | + raise KasaException( | ||
| 251 | 251 | f"Invalid index {index}, device has {len(self.children)} plugs" | |
| 252 | 252 | ) | |
| 253 | 253 | return self.children[index] | |
@@ -306,7 +306,7 @@ def _add_feature(self, feature: Feature): | |||
| 306 | 306 | """Add a new feature to the device.""" | |
| 307 | 307 | desc_name = feature.name.lower().replace(" ", "_") | |
| 308 | 308 | if desc_name in self._features: | |
| 309 | - raise SmartDeviceException("Duplicate feature name %s" % desc_name) | ||
| 309 | + raise KasaException("Duplicate feature name %s" % desc_name) | ||
| 310 | 310 | self._features[desc_name] = feature | |
| 311 | 311 | ||
| 312 | 312 | @property | |
| Back | FazBrowse Home | New Git URL |
0 commit comments