From bb6cd5952500f119a159c5fecb3af6e2b35d1551 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Tue, 27 Sep 2016 14:39:46 -0700 Subject: [PATCH] PYTHON-1157 SSL timeouts should raise NetworkTimeout, not AutoReconnect --- pymongo/pool.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pymongo/pool.py b/pymongo/pool.py index 10ab0ba6f..e9d829fa0 100644 --- a/pymongo/pool.py +++ b/pymongo/pool.py @@ -21,9 +21,13 @@ import threading try: import ssl + from ssl import SSLError _HAVE_SNI = getattr(ssl, 'HAS_SNI', False) except ImportError: _HAVE_SNI = False + class SSLError(socket.error): + pass + from bson import DEFAULT_CODEC_OPTIONS from bson.py3compat import imap, itervalues, _unicode @@ -195,6 +199,14 @@ def _raise_connection_failure(address, error): msg = '%s: %s' % (host, error) if isinstance(error, socket.timeout): raise NetworkTimeout(msg) + elif isinstance(error, SSLError) and 'timed out' in str(error): + # CPython 2.6, 2.7, PyPy 2.x, and PyPy3 do not distinguish network + # timeouts from other SSLErrors (https://bugs.python.org/issue10272). + # Luckily, we can work around this limitation because the phrase + # 'timed out' appears in all the timeout related SSLErrors raised + # on the above platforms. CPython >= 3.2 and PyPy3.3 correctly raise + # socket.timeout. + raise NetworkTimeout(msg) else: raise AutoReconnect(msg)