|
13 | 13 | from typing import Any, Protocol, TypeVar, overload |
14 | 14 |
|
15 | 15 | from roborock.data import RoborockBase, RRiot |
16 | | -from roborock.exceptions import RoborockException, RoborockUnsupportedFeature |
| 16 | +from roborock.exceptions import RoborockException, RoborockInvalidStatus, RoborockUnsupportedFeature |
17 | 17 | from roborock.protocol import Utils |
18 | 18 | from roborock.roborock_message import RoborockMessage, RoborockMessageProtocol |
19 | 19 | from roborock.roborock_typing import RoborockCommand |
@@ -106,6 +106,24 @@ def _as_payload(self, security_data: SecurityData | None) -> bytes: |
106 | 106 |
|
107 | 107 | ResponseData = dict[str, Any] | list | int |
108 | 108 |
|
| 109 | +# V1 RPC error code mappings to specific exception types |
| 110 | +_V1_ERROR_CODE_EXCEPTIONS: dict[int, type[RoborockException]] = { |
| 111 | + -10007: RoborockInvalidStatus, # "invalid status" - device action locked |
| 112 | +} |
| 113 | + |
| 114 | + |
| 115 | +def _create_api_error(error: Any) -> RoborockException: |
| 116 | + """Create an appropriate exception for a V1 RPC error response. |
| 117 | +
|
| 118 | + Maps known error codes to specific exception types for easier handling |
| 119 | + at higher levels. |
| 120 | + """ |
| 121 | + if isinstance(error, dict): |
| 122 | + code = error.get("code") |
| 123 | + if isinstance(code, int) and (exc_type := _V1_ERROR_CODE_EXCEPTIONS.get(code)): |
| 124 | + return exc_type(error) |
| 125 | + return RoborockException(error) |
| 126 | + |
109 | 127 |
|
110 | 128 | @dataclass(kw_only=True, frozen=True) |
111 | 129 | class ResponseMessage: |
@@ -156,7 +174,7 @@ def decode_rpc_response(message: RoborockMessage) -> ResponseMessage: |
156 | 174 | request_id: int | None = data_point_response.get("id") |
157 | 175 | api_error: RoborockException | None = None |
158 | 176 | if error := data_point_response.get("error"): |
159 | | - api_error = RoborockException(error) |
| 177 | + api_error = _create_api_error(error) |
160 | 178 |
|
161 | 179 | if (result := data_point_response.get("result")) is None: |
162 | 180 | # Some firmware versions return an error-only response (no "result" key). |
|
0 commit comments