diff options
| author | Andy McCurdy <andy@andymccurdy.com> | 2019-08-13 16:46:38 -0700 |
|---|---|---|
| committer | Andy McCurdy <andy@andymccurdy.com> | 2019-08-13 16:46:38 -0700 |
| commit | f0516c9f7589557883a5eb23a44531066e275950 (patch) | |
| tree | 096d920be07af7e98e31dabbe53b443bd63af6ab | |
| parent | 038e5ee019ecaa29b073a89e61585d404579beff (diff) | |
| download | redis-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-- | CHANGES | 4 | ||||
| -rw-r--r-- | redis/__init__.py | 2 | ||||
| -rwxr-xr-x | redis/connection.py | 20 |
3 files changed, 21 insertions, 5 deletions
@@ -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) |
