@@ -127,11 +127,13 @@ async def _send(self, message: str) -> None:
127
127
"""Send the provided message to the adapter connection and log the message"""
128
128
129
129
if not self ._connected :
130
- raise TransportClosed (
131
- "Transport is not connected"
132
- ) from self .close_exception
130
+ if isinstance (self .close_exception , TransportConnectionFailed ):
131
+ raise self .close_exception
132
+ else :
133
+ raise TransportConnectionFailed () from self .close_exception
133
134
134
135
try :
136
+ # Can raise TransportConnectionFailed
135
137
await self .adapter .send (message )
136
138
log .info (">>> %s" , message )
137
139
except TransportConnectionFailed as e :
@@ -143,7 +145,7 @@ async def _receive(self) -> str:
143
145
144
146
# It is possible that the connection has been already closed in another task
145
147
if not self ._connected :
146
- raise TransportClosed ( "Transport is already closed" )
148
+ raise TransportConnectionFailed () from self . close_exception
147
149
148
150
# Wait for the next frame.
149
151
# Can raise TransportConnectionFailed or TransportProtocolError
@@ -214,8 +216,6 @@ async def _receive_data_loop(self) -> None:
214
216
except (TransportConnectionFailed , TransportProtocolError ) as e :
215
217
await self ._fail (e , clean_close = False )
216
218
break
217
- except TransportClosed :
218
- break
219
219
220
220
# Parse the answer
221
221
try :
@@ -482,6 +482,10 @@ async def _close_coro(self, e: Exception, clean_close: bool = True) -> None:
482
482
# We should always have an active websocket connection here
483
483
assert self ._connected
484
484
485
+ # Saving exception to raise it later if trying to use the transport
486
+ # after it has already closed.
487
+ self .close_exception = e
488
+
485
489
# Properly shut down liveness checker if enabled
486
490
if self .check_keep_alive_task is not None :
487
491
# More info: https://stackoverflow.com/a/43810272/1113207
@@ -492,18 +496,17 @@ async def _close_coro(self, e: Exception, clean_close: bool = True) -> None:
492
496
# Calling the subclass close hook
493
497
await self ._close_hook ()
494
498
495
- # Saving exception to raise it later if trying to use the transport
496
- # after it has already closed.
497
- self .close_exception = e
498
-
499
499
if clean_close :
500
500
log .debug ("_close_coro: starting clean_close" )
501
501
try :
502
502
await self ._clean_close (e )
503
503
except Exception as exc : # pragma: no cover
504
504
log .warning ("Ignoring exception in _clean_close: " + repr (exc ))
505
505
506
- log .debug ("_close_coro: sending exception to listeners" )
506
+ if log .isEnabledFor (logging .DEBUG ):
507
+ log .debug (
508
+ f"_close_coro: sending exception to { len (self .listeners )} listeners"
509
+ )
507
510
508
511
# Send an exception to all remaining listeners
509
512
for query_id , listener in self .listeners .items ():
@@ -530,7 +533,15 @@ async def _close_coro(self, e: Exception, clean_close: bool = True) -> None:
530
533
log .debug ("_close_coro: exiting" )
531
534
532
535
async def _fail (self , e : Exception , clean_close : bool = True ) -> None :
533
- log .debug ("_fail: starting with exception: " + repr (e ))
536
+ if log .isEnabledFor (logging .DEBUG ):
537
+ import inspect
538
+
539
+ current_frame = inspect .currentframe ()
540
+ assert current_frame is not None
541
+ caller_frame = current_frame .f_back
542
+ assert caller_frame is not None
543
+ caller_name = inspect .getframeinfo (caller_frame ).function
544
+ log .debug (f"_fail from { caller_name } : " + repr (e ))
534
545
535
546
if self .close_task is None :
536
547
0 commit comments