summaryrefslogtreecommitdiff
path: root/redis/asyncio/connection.py
diff options
context:
space:
mode:
Diffstat (limited to 'redis/asyncio/connection.py')
-rw-r--r--redis/asyncio/connection.py28
1 files changed, 18 insertions, 10 deletions
diff --git a/redis/asyncio/connection.py b/redis/asyncio/connection.py
index 59f75aa..462673f 100644
--- a/redis/asyncio/connection.py
+++ b/redis/asyncio/connection.py
@@ -804,7 +804,11 @@ class Connection:
raise ConnectionError(
f"Error {err_no} while writing to socket. {errmsg}."
) from e
- except Exception:
+ except BaseException:
+ # BaseExceptions can be raised when a socket send operation is not
+ # finished, e.g. due to a timeout. Ideally, a caller could then re-try
+ # to send un-sent data. However, the send_packed_command() API
+ # does not support it so there is no point in keeping the connection open.
await self.disconnect(nowait=True)
raise
@@ -828,6 +832,8 @@ class Connection:
self,
disable_decoding: bool = False,
timeout: Optional[float] = None,
+ *,
+ disconnect_on_error: bool = True,
):
"""Read the response from a previously sent command"""
read_timeout = timeout if timeout is not None else self.socket_timeout
@@ -843,22 +849,24 @@ class Connection:
)
except asyncio.TimeoutError:
if timeout is not None:
- # user requested timeout, return None
+ # user requested timeout, return None. Operation can be retried
return None
# it was a self.socket_timeout error.
- await self.disconnect(nowait=True)
+ if disconnect_on_error:
+ await self.disconnect(nowait=True)
raise TimeoutError(f"Timeout reading from {self.host}:{self.port}")
except OSError as e:
- await self.disconnect(nowait=True)
+ if disconnect_on_error:
+ await self.disconnect(nowait=True)
raise ConnectionError(
f"Error while reading from {self.host}:{self.port} : {e.args}"
)
- except asyncio.CancelledError:
- # need this check for 3.7, where CancelledError
- # is subclass of Exception, not BaseException
- raise
- except Exception:
- await self.disconnect(nowait=True)
+ except BaseException:
+ # Also by default close in case of BaseException. A lot of code
+ # relies on this behaviour when doing Command/Response pairs.
+ # See #1128.
+ if disconnect_on_error:
+ await self.disconnect(nowait=True)
raise
if self.health_check_interval: