@@ -96,6 +96,27 @@ def anonymise_sensitive_params(params, sensitive_params):
9696
9797 return params
9898
99+
100+ def _iter_error_types (error_type ):
101+ yield error_type
102+ for subclass in error_type .__subclasses__ ():
103+ yield from _iter_error_types (subclass )
104+
105+
106+ def build_error (error ):
107+ data = error .setdefault ("data" , None )
108+ code = error .setdefault ("code" , 0 )
109+ message = error .setdefault ("message" , "" )
110+
111+ if isinstance (data , Mapping ):
112+ internal_type = data .get ("internal_type" )
113+ if internal_type :
114+ for error_type in _iter_error_types (JsonRpcError ):
115+ if error_type .__name__ == internal_type :
116+ return error_type (message , data )
117+
118+ return JsonRpcError (code , message , data )
119+
99120class Connection ():
100121 def __init__ (self , reader , writer , encoder = json .JSONEncoder ()):
101122 self ._active = True
@@ -192,6 +213,10 @@ def close(self):
192213 if self ._active :
193214 logger .info ("Closing JSON-RPC server - not more messages will be read" )
194215 self ._active = False
216+ for request_id , (future , _ ) in self ._requests_futures .items ():
217+ if not future .done ():
218+ future .set_exception (Aborted (data = {"request_id" : request_id }))
219+ self ._requests_futures .clear ()
195220
196221 async def wait_closed (self ):
197222 await self ._task_manager .wait ()
@@ -216,7 +241,13 @@ def _handle_input(self, data):
216241 self ._handle_response (message )
217242
218243 def _handle_response (self , response ):
219- request_future = self ._requests_futures .get (int (response .id ))
244+ try :
245+ request_id = int (response .id )
246+ except (TypeError , ValueError ):
247+ logger .warning ("Received response with invalid request id: %s" , response .id )
248+ return
249+
250+ request_future = self ._requests_futures .pop (request_id , None )
220251 if request_future is None :
221252 response_type = "response" if response .result is not None else "error"
222253 logger .warning ("Received %s for unknown request: %s" , response_type , response .id )
@@ -225,11 +256,7 @@ def _handle_response(self, response):
225256 future , sensitive_params = request_future
226257
227258 if response .error :
228- error = JsonRpcError (
229- response .error .setdefault ("code" , 0 ),
230- response .error .setdefault ("message" , "" ),
231- response .error .setdefault ("data" , None )
232- )
259+ error = build_error (response .error )
233260 self ._log_error (response , error , sensitive_params )
234261 future .set_exception (error )
235262 return
@@ -249,7 +276,8 @@ def _handle_notification(self, request):
249276 try :
250277 bound_args = signature .bind (** request .params )
251278 except TypeError :
252- self ._send_error (request .id , InvalidParams ())
279+ logger .error ("Received notification with invalid params: %s" , request .method )
280+ return
253281
254282 if immediate :
255283 callback (* bound_args .args , ** bound_args .kwargs )
@@ -273,6 +301,7 @@ def _handle_request(self, request):
273301 bound_args = signature .bind (** request .params )
274302 except TypeError :
275303 self ._send_error (request .id , InvalidParams ())
304+ return
276305
277306 if immediate :
278307 response = callback (* bound_args .args , ** bound_args .kwargs )
0 commit comments