<p dir="auto">Requests fail while trying to format exception related to non-existent CA file.</p>
<p dir="auto">Code to reproduce:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import requests
requests.get('https://google.com', verify='/some/some')"><pre class="notranslate"><code class="notranslate">import requests
requests.get('https://google.com', verify='/some/some')
</code></pre></div>
<p dir="auto">results in:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  File &quot;/Users/traut/.p/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py&quot;, line 559, in urlopen
    body=body, headers=headers)
  File &quot;/Users/traut/.p/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py&quot;, line 348, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
  File &quot;/Users/traut/.p/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py&quot;, line 318, in _raise_timeout
    if 'timed out' in str(err) or 'did not complete (read)' in str(err):  # Python 2.6
TypeError: __str__ returned non-string (type Error)"><pre class="notranslate"><code class="notranslate">  File "/Users/traut/.p/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 559, in urlopen
    body=body, headers=headers)
  File "/Users/traut/.p/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 348, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
  File "/Users/traut/.p/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 318, in _raise_timeout
    if 'timed out' in str(err) or 'did not complete (read)' in str(err):  # Python 2.6
TypeError: __str__ returned non-string (type Error)
</code></pre></div>
<p dir="auto">Versions:<br>
Python 2.7.10<br>
Requests 2.8.1</p>
<p dir="auto">If an <code class="notranslate">SSLError</code> comes from <code class="notranslate">pyOpenSSL</code>, we attempt to determine if it's an error due to request timeouts on python 2.6 being raised as <code class="notranslate">BaseSSLErrors</code> <a href="https://github.com/shazow/urllib3/blob/29aa09bde9c42cc9a8d79aac47ee3d362b438cca/urllib3/connectionpool.py#L314">here</a>. If the handshake ends unexpectedly under pyOpenSSL, then we get an <code class="notranslate">SSLError</code> that has a captured <code class="notranslate">SysCallError</code> which when you call <code class="notranslate">str(SSLError(msg, SysCallError(code, msg)))</code> you get</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="TypeError: __str__ returned non-string (type SysCallError)"><pre class="notranslate"><span class="pl-v">TypeError</span>: <span class="pl-s1">__str__</span> <span class="pl-s1">returned</span> <span class="pl-s1">non</span><span class="pl-c1">-</span><span class="pl-en">string</span> (<span class="pl-s1">type</span> <span class="pl-v">SysCallError</span>)</pre></div>
<p dir="auto">So we might want to update how we handle SSLErrors to accomodate pyOpenSSL. To be clear, I observed this on: python 2.7.9 with openssl 1.0.1l (from brew) and I was using requests to debug an issue with <code class="notranslate">https://apissl.cloudfactory.com</code>, e.g., <code class="notranslate">requests.get('https://apissl.cloudfactory.com')</code></p>