summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy McCurdy <andy@andymccurdy.com>2019-08-13 16:46:38 -0700
committerAndy McCurdy <andy@andymccurdy.com>2019-08-13 16:46:38 -0700
commitf0516c9f7589557883a5eb23a44531066e275950 (patch)
tree096d920be07af7e98e31dabbe53b443bd63af6ab
parent038e5ee019ecaa29b073a89e61585d404579beff (diff)
downloadredis-py-f0516c9f7589557883a5eb23a44531066e275950.tar.gz
version 3.3.7, Fixed a socket.error regression introduced in 3.3.03.3.7
Prior versions of 3.3.x could potentially raise a raw socket.error (or one of its subclasses) instead of a redis.exceptions.ConnectionError. Fixes #1202
-rw-r--r--CHANGES4
-rw-r--r--redis/__init__.py2
-rwxr-xr-xredis/connection.py20
3 files changed, 21 insertions, 5 deletions
diff --git a/CHANGES b/CHANGES
index cc61dad..eda80b6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+* 3.3.7
+ * Fixed a regression introduced in 3.3.0 where socket.error exceptions
+ (or subclasses) could potentially be raised instead of
+ redis.exceptions.ConnectionError. #1202
* 3.3.6
* Fixed a regression in 3.3.5 that caused PubSub.get_message() to raise
a socket.timeout exception when passing a timeout value. #1200
diff --git a/redis/__init__.py b/redis/__init__.py
index 6200d4d..bfd1839 100644
--- a/redis/__init__.py
+++ b/redis/__init__.py
@@ -29,7 +29,7 @@ def int_or_str(value):
return value
-__version__ = '3.3.6'
+__version__ = '3.3.7'
VERSION = tuple(map(int_or_str, __version__.split('.')))
__all__ = [
diff --git a/redis/connection.py b/redis/connection.py
index 3a0ae65..333bd75 100755
--- a/redis/connection.py
+++ b/redis/connection.py
@@ -46,6 +46,16 @@ if ssl_available:
else:
NONBLOCKING_EXCEPTION_ERROR_NUMBERS[ssl.SSLError] = 2
+# In Python 2.7 a socket.error is raised for a nonblocking read.
+# The _compat module aliases BlockingIOError to socket.error to be
+# Python 2/3 compatible.
+# However this means that all socket.error exceptions need to be handled
+# properly within these exception handlers.
+# We need to make sure socket.error is included in these handlers and
+# provide a dummy error number that will never match a real exception.
+if socket.error not in NONBLOCKING_EXCEPTION_ERROR_NUMBERS:
+ NONBLOCKING_EXCEPTION_ERROR_NUMBERS[socket.error] = -999999
+
NONBLOCKING_EXCEPTIONS = tuple(NONBLOCKING_EXCEPTION_ERROR_NUMBERS.keys())
if HIREDIS_AVAILABLE:
@@ -184,7 +194,7 @@ class SocketBuffer(object):
return True
except socket.timeout:
if raise_on_timeout:
- raise
+ raise TimeoutError("Timeout reading from socket")
return False
except NONBLOCKING_EXCEPTIONS as ex:
# if we're in nonblocking mode and the recv raises a
@@ -194,7 +204,8 @@ class SocketBuffer(object):
allowed = NONBLOCKING_EXCEPTION_ERROR_NUMBERS.get(ex.__class__, -1)
if not raise_on_timeout and ex.errno == allowed:
return False
- raise
+ raise ConnectionError("Error while reading from socket: %s" %
+ (ex.args,))
finally:
if custom_timeout:
sock.settimeout(self.socket_timeout)
@@ -414,7 +425,7 @@ class HiredisParser(BaseParser):
return True
except socket.timeout:
if raise_on_timeout:
- raise
+ raise TimeoutError("Timeout reading from socket")
return False
except NONBLOCKING_EXCEPTIONS as ex:
# if we're in nonblocking mode and the recv raises a
@@ -424,7 +435,8 @@ class HiredisParser(BaseParser):
allowed = NONBLOCKING_EXCEPTION_ERROR_NUMBERS.get(ex.__class__, -1)
if not raise_on_timeout and ex.errno == allowed:
return False
- raise
+ raise ConnectionError("Error while reading from socket: %s" %
+ (ex.args,))
finally:
if custom_timeout:
sock.settimeout(self._socket_timeout)