@@ -804,7 +804,11 @@ async def send_packed_command(
804
804
raise ConnectionError (
805
805
f"Error { err_no } while writing to socket. { errmsg } ."
806
806
) from e
807
- except Exception :
807
+ except BaseException :
808
+ # BaseExceptions can be raised when a socket send operation is not
809
+ # finished, e.g. due to a timeout. Ideally, a caller could then re-try
810
+ # to send un-sent data. However, the send_packed_command() API
811
+ # does not support it so there is no point in keeping the connection open.
808
812
await self .disconnect (nowait = True )
809
813
raise
810
814
@@ -827,7 +831,9 @@ async def can_read_destructive(self):
827
831
async def read_response (
828
832
self ,
829
833
disable_decoding : bool = False ,
834
+ * ,
830
835
timeout : Optional [float ] = None ,
836
+ disconnect_on_error : bool = True ,
831
837
):
832
838
"""Read the response from a previously sent command"""
833
839
read_timeout = timeout if timeout is not None else self .socket_timeout
@@ -843,22 +849,24 @@ async def read_response(
843
849
)
844
850
except asyncio .TimeoutError :
845
851
if timeout is not None :
846
- # user requested timeout, return None
852
+ # user requested timeout, return None. Operation can be retried
847
853
return None
848
854
# it was a self.socket_timeout error.
849
- await self .disconnect (nowait = True )
855
+ if disconnect_on_error :
856
+ await self .disconnect (nowait = True )
850
857
raise TimeoutError (f"Timeout reading from { self .host } :{ self .port } " )
851
858
except OSError as e :
852
- await self .disconnect (nowait = True )
859
+ if disconnect_on_error :
860
+ await self .disconnect (nowait = True )
853
861
raise ConnectionError (
854
862
f"Error while reading from { self .host } :{ self .port } : { e .args } "
855
863
)
856
- except asyncio . CancelledError :
857
- # need this check for 3.7, where CancelledError
858
- # is subclass of Exception, not BaseException
859
- raise
860
- except Exception :
861
- await self .disconnect (nowait = True )
864
+ except BaseException :
865
+ # Also by default close in case of BaseException. A lot of code
866
+ # relies on this behaviour when doing Command/Response pairs.
867
+ # See #1128.
868
+ if disconnect_on_error :
869
+ await self .disconnect (nowait = True )
862
870
raise
863
871
864
872
if self .health_check_interval :
0 commit comments