@@ -108,9 +108,18 @@ class ResponseMessage:
108108 data : ResponseData
109109 """The data of the response, where the type depends on the command."""
110110
111+ api_error : RoborockException | None = None
112+ """The API error message of the response if any."""
113+
111114
112115def decode_rpc_response (message : RoborockMessage ) -> ResponseMessage :
113- """Decode a V1 RPC_RESPONSE message."""
116+ """Decode a V1 RPC_RESPONSE message.
117+
118+ This will raise a RoborockException if the message cannot be parsed. A
119+ response object will be returned even if there is an error in the
120+ response, as long as we can extract the request ID. This is so we can
121+ associate an API response with a request even if there was an error.
122+ """
114123 if not message .payload :
115124 return ResponseMessage (request_id = message .seq , data = {})
116125 try :
@@ -136,19 +145,26 @@ def decode_rpc_response(message: RoborockMessage) -> ResponseMessage:
136145 ) from e
137146
138147 request_id : int | None = data_point_response .get ("id" )
148+ exc : RoborockException | None = None
139149 if error := data_point_response .get ("error" ):
140- raise RoborockException (f"Error in message: { error } " )
141-
150+ exc = RoborockException (error )
142151 if not (result := data_point_response .get ("result" )):
143- raise RoborockException (f"Invalid V1 message format: missing 'result' in data point for { message .payload !r} " )
144- _LOGGER .debug ("Decoded V1 message result: %s" , result )
145- if isinstance (result , str ) and result == "ok" :
146- result = {}
147- if not isinstance (result , (dict , list , int )):
148- raise RoborockException (
149- f"Invalid V1 message format: 'result' was unexpected type { type (result )} . { message .payload !r} "
150- )
151- return ResponseMessage (request_id = request_id , data = result )
152+ exc = RoborockException (f"Invalid V1 message format: missing 'result' in data point for { message .payload !r} " )
153+ else :
154+ _LOGGER .debug ("Decoded V1 message result: %s" , result )
155+ if isinstance (result , str ):
156+ if result == "unknown_method" :
157+ exc = RoborockException ("The method called is not recognized by the device." )
158+ elif result != "ok" :
159+ exc = RoborockException (f"Unexpected API Result: { result } " )
160+ result = {}
161+ if not isinstance (result , (dict , list , int )):
162+ raise RoborockException (
163+ f"Invalid V1 message format: 'result' was unexpected type { type (result )} . { message .payload !r} "
164+ )
165+ if not request_id and exc :
166+ raise exc
167+ return ResponseMessage (request_id = request_id , data = result , api_error = exc )
152168
153169
154170@dataclass
0 commit comments