@@ -624,7 +624,65 @@ def set_result(f: asyncio.Future[Any], r: Any, ev: threading.Event) -> None:
624624
625625 @__logger .call
626626 async def handle_error (self , message : JsonRPCError ) -> None :
627- raise JsonRPCErrorException (message .error .code , message .error .message , message .error .data )
627+ if message .id is None :
628+ error = "Invalid response. Response id is null."
629+ self .__logger .warning (error )
630+ raise JsonRPCErrorException (message .error .code , message .error .message , message .error .data )
631+
632+ with self ._sended_request_lock :
633+ entry = self ._sended_request .pop (message .id , None )
634+
635+ if entry is None :
636+ error = f"Invalid response. Could not find id '{ message .id } ' in request list."
637+ self .__logger .warning (error )
638+ raise JsonRPCErrorException (message .error .code , message .error .message , message .error .data )
639+
640+ try :
641+ if not entry .future .done ():
642+ res = None
643+ if message .result is not None :
644+ res = from_dict (message .result , entry .result_type )
645+ if entry .future .get_loop () == asyncio .get_running_loop ():
646+ entry .future .set_exception (
647+ JsonRPCErrorException (message .error .code , message .error .message , message .error .data )
648+ )
649+ else :
650+ if entry .future .get_loop ().is_running ():
651+
652+ def set_result (f : asyncio .Future [Any ], r : Any , ev : threading .Event ) -> None :
653+ try :
654+ if not f .done () and f .get_loop ().is_running ():
655+ f .set_exception (
656+ JsonRPCErrorException (
657+ message .error .code , message .error .message , message .error .data
658+ )
659+ )
660+ finally :
661+ ev .set ()
662+
663+ done = threading .Event ()
664+
665+ entry .future .get_loop ().call_soon_threadsafe (set_result , entry .future , res , done )
666+
667+ start = time .monotonic ()
668+ while not done .is_set ():
669+ if time .monotonic () - start > 120 :
670+ raise TimeoutError ("Can't set future result." )
671+
672+ await asyncio .sleep (0 )
673+
674+ else :
675+ self .__logger .warning (lambda : f"Response { entry !r} loop is not running." )
676+
677+ except (SystemExit , KeyboardInterrupt ):
678+ raise
679+ except BaseException as e :
680+ if not entry .future .done ():
681+ if entry .future .get_loop () == asyncio .get_running_loop ():
682+ entry .future .set_exception (e )
683+ else :
684+ if entry .future .get_loop ().is_running ():
685+ entry .future .get_loop ().call_soon_threadsafe (entry .future .set_exception , e )
628686
629687 @staticmethod
630688 def _convert_params (
0 commit comments