Skip to content

Commit 7dccb43

Browse files
committed
Make disconnect_on_error optional for Connection.read_response()
1 parent 8cbd128 commit 7dccb43

File tree

4 files changed

+27
-16
lines changed

4 files changed

+27
-16
lines changed

redis/asyncio/client.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,9 @@ async def parse_response(self, block: bool = True, timeout: float = 0):
781781
await conn.connect()
782782

783783
read_timeout = None if block else timeout
784-
response = await self._execute(conn, conn.read_response, timeout=read_timeout)
784+
response = await self._execute(
785+
conn, conn.read_response, timeout=read_timeout, disconnect_on_error=False
786+
)
785787

786788
if conn.health_check_interval and response == self.health_check_response:
787789
# ignore the health check message as user might not expect it

redis/asyncio/connection.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ async def read_response(
787787
self,
788788
disable_decoding: bool = False,
789789
timeout: Optional[float] = None,
790+
disconnect_on_error: bool = True,
790791
):
791792
"""Read the response from a previously sent command"""
792793
read_timeout = timeout if timeout is not None else self.socket_timeout
@@ -802,22 +803,24 @@ async def read_response(
802803
)
803804
except asyncio.TimeoutError:
804805
if timeout is not None:
805-
# user requested timeout, return None
806+
# user requested timeout, return None. Operation can be retried
806807
return None
807808
# it was a self.socket_timeout error.
808-
await self.disconnect(nowait=True)
809+
if disconnect_on_error:
810+
await self.disconnect(nowait=True)
809811
raise TimeoutError(f"Timeout reading from {self.host}:{self.port}")
810812
except OSError as e:
811-
await self.disconnect(nowait=True)
813+
if disconnect_on_error:
814+
await self.disconnect(nowait=True)
812815
raise ConnectionError(
813816
f"Error while reading from {self.host}:{self.port} : {e.args}"
814817
)
815-
except asyncio.CancelledError:
816-
# need this check for 3.7, where CancelledError
817-
# is subclass of Exception, not BaseException
818-
raise
819-
except Exception:
820-
await self.disconnect(nowait=True)
818+
except BaseException:
819+
# Also by default close in case of BaseException. A lot of code
820+
# relies on this behaviour when doing Command/Response pairs.
821+
# See #1128.
822+
if disconnect_on_error:
823+
await self.disconnect(nowait=True)
821824
raise
822825

823826
if self.health_check_interval:

redis/client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1526,7 +1526,7 @@ def try_read():
15261526
return None
15271527
else:
15281528
conn.connect()
1529-
return conn.read_response()
1529+
return conn.read_response(disconnect_on_error=False)
15301530

15311531
response = self._execute(conn, try_read)
15321532

redis/connection.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ def can_read(self, timeout=0):
801801
f"Error while reading from {self.host}:{self.port}: {e.args}"
802802
)
803803

804-
def read_response(self, disable_decoding=False):
804+
def read_response(self, disable_decoding=False, disconnect_on_error: bool = True):
805805
"""Read the response from a previously sent command"""
806806
try:
807807
hosterr = f"{self.host}:{self.port}"
@@ -811,13 +811,19 @@ def read_response(self, disable_decoding=False):
811811
try:
812812
response = self._parser.read_response(disable_decoding=disable_decoding)
813813
except socket.timeout:
814-
self.disconnect()
814+
if disconnect_on_error:
815+
self.disconnect()
815816
raise TimeoutError(f"Timeout reading from {hosterr}")
816817
except OSError as e:
817-
self.disconnect()
818+
if disconnect_on_error:
819+
self.disconnect()
818820
raise ConnectionError(f"Error while reading from {hosterr}" f" : {e.args}")
819-
except Exception:
820-
self.disconnect()
821+
except BaseException:
822+
# Also by default close in case of BaseException. A lot of code
823+
# relies on this behaviour when doing Command/Response pairs.
824+
# See #1128.
825+
if disconnect_on_error:
826+
self.disconnect()
821827
raise
822828

823829
if self.health_check_interval:

0 commit comments

Comments
 (0)