5
5
import json
6
6
import logging
7
7
import threading
8
+ import traceback
8
9
from collections import OrderedDict
9
10
from typing import (
10
11
Any ,
@@ -98,7 +99,11 @@ def send_message(self, message: ProtocolMessage) -> None:
98
99
)
99
100
100
101
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 )
102
107
103
108
def send_error (
104
109
self ,
@@ -123,19 +128,10 @@ def _generate_json_rpc_messages_from_dict(
123
128
data : Union [Dict [Any , Any ], List [Dict [Any , Any ]]]
124
129
) -> Iterator [ProtocolMessage ]:
125
130
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
139
135
140
136
if isinstance (data , list ):
141
137
for e in data :
@@ -150,7 +146,10 @@ def _handle_body(self, body: bytes, charset: str) -> None:
150
146
raise
151
147
except BaseException as e :
152
148
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
+ )
154
153
155
154
def _handle_messages (self , iterator : Iterator [ProtocolMessage ]) -> None :
156
155
def done (f : asyncio .Future [Any ]) -> None :
@@ -165,13 +164,13 @@ def done(f: asyncio.Future[Any]) -> None:
165
164
@_logger .call
166
165
async def handle_message (self , message : ProtocolMessage ) -> None :
167
166
if isinstance (message , Request ):
168
- await self .handle_request (message )
167
+ self .handle_request (message )
169
168
if isinstance (message , Event ):
170
- await self .handle_event (message )
169
+ self .handle_event (message )
171
170
elif isinstance (message , ErrorResponse ):
172
- await self .handle_error_response (message )
171
+ self .handle_error_response (message )
173
172
elif isinstance (message , Response ):
174
- await self .handle_response (message )
173
+ self .handle_response (message )
175
174
176
175
@staticmethod
177
176
def _convert_params (
@@ -237,56 +236,57 @@ async def handle_unknown_command(self, message: Request) -> Any:
237
236
)
238
237
239
238
@_logger .call
240
- async def handle_request (self , message : Request ) -> None :
239
+ def handle_request (self , message : Request ) -> None :
241
240
e = self .registry .get_entry (message .command )
242
241
243
- try :
242
+ with self . _received_request_lock :
244
243
if e is None or not callable (e .method ):
245
244
result = asyncio .create_task (self .handle_unknown_command (message ))
246
245
else :
247
246
params = self ._convert_params (e .method , e .param_type , message .arguments )
248
247
249
248
result = asyncio .create_task (ensure_coroutine (e .method )(* params [0 ], ** params [1 ]))
250
249
251
- with self ._received_request_lock :
252
- self ._received_request [message .seq ] = result
250
+ self ._received_request [message .seq ] = result
253
251
252
+ def done (t : asyncio .Task [Any ]) -> None :
254
253
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
+ )
256
285
finally :
257
286
with self ._received_request_lock :
258
287
self ._received_request .pop (message .seq , None )
259
288
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 )
290
290
291
291
@_logger .call
292
292
def send_response (
@@ -332,26 +332,23 @@ async def send_event_async(self, event: Event) -> None:
332
332
self .send_event (event )
333
333
334
334
@_logger .call
335
- async def handle_error_response (self , message : ErrorResponse ) -> None :
335
+ def handle_error_response (self , message : ErrorResponse ) -> None :
336
336
with self ._sended_request_lock :
337
337
entry = self ._sended_request .pop (message .request_seq , None )
338
338
339
339
exception = DebugAdapterErrorResponseError (message )
340
340
if entry is None :
341
341
raise exception
342
342
343
- try :
344
- entry .future .set_exception (exception )
345
- except (SystemExit , KeyboardInterrupt ):
346
- raise
343
+ entry .future .set_exception (exception )
347
344
348
345
@_logger .call
349
- async def handle_response (self , message : Response ) -> None :
346
+ def handle_response (self , message : Response ) -> None :
350
347
with self ._sended_request_lock :
351
348
entry = self ._sended_request .pop (message .request_seq , None )
352
349
353
350
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 } "
355
352
self ._logger .warning (error )
356
353
self .send_error ("invalid response" , error_message = Message (format = error , show_user = True ))
357
354
return
@@ -369,5 +366,5 @@ async def handle_response(self, message: Response) -> None:
369
366
entry .future .set_exception (e )
370
367
371
368
@_logger .call
372
- async def handle_event (self , message : Event ) -> None :
369
+ def handle_event (self , message : Event ) -> None :
373
370
raise NotImplementedError ()
0 commit comments