55import json
66import logging
77import threading
8+ import traceback
89from collections import OrderedDict
910from typing import (
1011 Any ,
@@ -98,7 +99,11 @@ def send_message(self, message: ProtocolMessage) -> None:
9899 )
99100
100101 if self .write_transport is not None :
101- self .write_transport .write (header + body )
102+ msg = header + body
103+ if self ._loop == asyncio .get_running_loop ():
104+ self .write_transport .write (msg )
105+ elif self ._loop is not None :
106+ self ._loop .call_soon_threadsafe (self .write_transport .write , msg )
102107
103108 def send_error (
104109 self ,
@@ -123,19 +128,10 @@ def _generate_json_rpc_messages_from_dict(
123128 data : Union [Dict [Any , Any ], List [Dict [Any , Any ]]]
124129 ) -> Iterator [ProtocolMessage ]:
125130 def inner (d : Dict [Any , Any ]) -> ProtocolMessage :
126- # if "type" in d:
127- # type = d.get("type")
128- # if type == "request":
129- # return Request(**d)
130- # elif type == "response":
131- # if "success" in d and d["success"] is not True:
132- # return ErrorResponse(**d)
133- # return Response(**d)
134- # elif type == "event":
135- # return Event(**d)
136-
137- # raise JsonRPCException(f"Invalid Debug Adapter Message {repr(d)}")
138- return from_dict (d , (Request , Response , Event )) # type: ignore
131+ result = from_dict (d , (Request , Response , Event )) # type: ignore
132+ if isinstance (result , Response ) and not result .success :
133+ result = from_dict (d , ErrorResponse )
134+ return result # type: ignore
139135
140136 if isinstance (data , list ):
141137 for e in data :
@@ -150,7 +146,10 @@ def _handle_body(self, body: bytes, charset: str) -> None:
150146 raise
151147 except BaseException as e :
152148 self ._logger .exception (e )
153- self .send_error (f"Invalid Message: { type (e ).__name__ } : { str (e )} -> { str (body )} " )
149+ self .send_error (
150+ f"Invalid Message: { type (e ).__name__ } : { str (e )} -> { str (body )} \n { traceback .format_exc ()} " ,
151+ error_message = Message (traceback .format_exc ()),
152+ )
154153
155154 def _handle_messages (self , iterator : Iterator [ProtocolMessage ]) -> None :
156155 def done (f : asyncio .Future [Any ]) -> None :
@@ -165,13 +164,13 @@ def done(f: asyncio.Future[Any]) -> None:
165164 @_logger .call
166165 async def handle_message (self , message : ProtocolMessage ) -> None :
167166 if isinstance (message , Request ):
168- await self .handle_request (message )
167+ self .handle_request (message )
169168 if isinstance (message , Event ):
170- await self .handle_event (message )
169+ self .handle_event (message )
171170 elif isinstance (message , ErrorResponse ):
172- await self .handle_error_response (message )
171+ self .handle_error_response (message )
173172 elif isinstance (message , Response ):
174- await self .handle_response (message )
173+ self .handle_response (message )
175174
176175 @staticmethod
177176 def _convert_params (
@@ -237,56 +236,57 @@ async def handle_unknown_command(self, message: Request) -> Any:
237236 )
238237
239238 @_logger .call
240- async def handle_request (self , message : Request ) -> None :
239+ def handle_request (self , message : Request ) -> None :
241240 e = self .registry .get_entry (message .command )
242241
243- try :
242+ with self . _received_request_lock :
244243 if e is None or not callable (e .method ):
245244 result = asyncio .create_task (self .handle_unknown_command (message ))
246245 else :
247246 params = self ._convert_params (e .method , e .param_type , message .arguments )
248247
249248 result = asyncio .create_task (ensure_coroutine (e .method )(* params [0 ], ** params [1 ]))
250249
251- with self ._received_request_lock :
252- self ._received_request [message .seq ] = result
250+ self ._received_request [message .seq ] = result
253251
252+ def done (t : asyncio .Task [Any ]) -> None :
254253 try :
255- self .send_response (message .seq , message .command , await result )
254+ self .send_response (message .seq , message .command , t .result ())
255+ except asyncio .CancelledError :
256+ self ._logger .info (f"request message { repr (message )} canceled" )
257+ except (SystemExit , KeyboardInterrupt ):
258+ raise
259+ except DebugAdapterRPCErrorException as ex :
260+ self ._logger .exception (ex )
261+ self .send_error (
262+ message = ex .message ,
263+ request_seq = message .seq ,
264+ command = ex .command or message .command ,
265+ success = ex .success or False ,
266+ error_message = ex .error_message ,
267+ )
268+ except DebugAdapterErrorResponseError as ex :
269+ self .send_error (
270+ ex .error .message ,
271+ message .seq ,
272+ message .command ,
273+ False ,
274+ error_message = ex .error .body .error if ex .error .body is not None else None ,
275+ )
276+ except BaseException as e :
277+ self ._logger .exception (e )
278+ self .send_error (
279+ str (type (e ).__name__ ),
280+ message .seq ,
281+ message .command ,
282+ False ,
283+ error_message = Message (format = f"{ type (e ).__name__ } : { e } " , show_user = True ),
284+ )
256285 finally :
257286 with self ._received_request_lock :
258287 self ._received_request .pop (message .seq , None )
259288
260- except asyncio .CancelledError :
261- self ._logger .info (f"request message { repr (message )} canceled" )
262- except (SystemExit , KeyboardInterrupt ):
263- raise
264- except DebugAdapterRPCErrorException as ex :
265- self ._logger .exception (ex )
266- self .send_error (
267- message = ex .message ,
268- request_seq = message .seq ,
269- command = ex .command or message .command ,
270- success = ex .success or False ,
271- error_message = ex .error_message ,
272- )
273- except DebugAdapterErrorResponseError as ex :
274- self .send_error (
275- ex .error .message ,
276- message .seq ,
277- message .command ,
278- False ,
279- error_message = ex .error .body .error if ex .error .body is not None else None ,
280- )
281- except BaseException as e :
282- self ._logger .exception (e )
283- self .send_error (
284- str (type (e ).__name__ ),
285- message .seq ,
286- message .command ,
287- False ,
288- error_message = Message (format = f"{ type (e ).__name__ } : { e } " , show_user = True ),
289- )
289+ result .add_done_callback (done )
290290
291291 @_logger .call
292292 def send_response (
@@ -332,26 +332,23 @@ async def send_event_async(self, event: Event) -> None:
332332 self .send_event (event )
333333
334334 @_logger .call
335- async def handle_error_response (self , message : ErrorResponse ) -> None :
335+ def handle_error_response (self , message : ErrorResponse ) -> None :
336336 with self ._sended_request_lock :
337337 entry = self ._sended_request .pop (message .request_seq , None )
338338
339339 exception = DebugAdapterErrorResponseError (message )
340340 if entry is None :
341341 raise exception
342342
343- try :
344- entry .future .set_exception (exception )
345- except (SystemExit , KeyboardInterrupt ):
346- raise
343+ entry .future .set_exception (exception )
347344
348345 @_logger .call
349- async def handle_response (self , message : Response ) -> None :
346+ def handle_response (self , message : Response ) -> None :
350347 with self ._sended_request_lock :
351348 entry = self ._sended_request .pop (message .request_seq , None )
352349
353350 if entry is None :
354- error = f"Invalid response. Could not find id '{ message .request_seq } ' in our request list"
351+ error = f"Invalid response. Could not find id '{ message .request_seq } ' in request list { message !r } "
355352 self ._logger .warning (error )
356353 self .send_error ("invalid response" , error_message = Message (format = error , show_user = True ))
357354 return
@@ -369,5 +366,5 @@ async def handle_response(self, message: Response) -> None:
369366 entry .future .set_exception (e )
370367
371368 @_logger .call
372- async def handle_event (self , message : Event ) -> None :
369+ def handle_event (self , message : Event ) -> None :
373370 raise NotImplementedError ()
0 commit comments