[Python-Dev] Proposal for better SSL errors

Antoine Pitrou solipsis at pitrou.net
Sun May 27 11:29:15 CEST 2012


On Sun, 27 May 2012 12:00:57 +1000
Cameron Simpson <cs at zip.com.au> wrote:
> On 26May2012 21:28, Antoine Pitrou <solipsis at pitrou.net> wrote:
> | Not only does the error string contain more valuable information (the
> | mnemonics "SSL" and "CERTIFICATE_VERIFY_FAILED" indicate, respectively,
> | in which subpart of OpenSSL and which precise error occurred), but they
> | are also introspectable:
> | 
> | >>> e = sys.last_value
> | >>> e.library
> | 'SSL'
> | >>> e.reason
> | 'CERTIFICATE_VERIFY_FAILED'
> | 
> | (these mnemonics correspond to OpenSSL's own #define'd numeric codes. I
> | find it more Pythonic to expose the mnemonics than the numbers, though.
> | Of course, the numbers <-> mnemnonics mappings can be separately
> | exposed)
> 
> Would you be inclined to exposed both? Eg add .ssl_errno (or whatever
> short name is conventionally used in the SSL library itself, just as
> "errno" matches the POSIX error code name).

OpenSSL has a diversity of error codes. In this case there's the result
code returned by OpenSSL's SSL_get_error(), which is 1 (SSL_ERROR_SSL)
and is already recorded as "errno" (see below). There's the reason,
as returned by OpenSSL's ERR_get_reason(), which is
SSL_R_CERTIFICATE_VERIFY_FAILED. And I'm sure other oddities are
lurking.

> | You'll note there is still a "Errno 5" in that error message; I don't
> | really know what to do with it. Hard-wiring the errno attribute to
> | something like None *might* break existing software, although that
> | would be unlikely since the current errno value is quite meaningless
> | and confusing (it has nothing to do with POSIX errnos).
> 
> It is EIO ("I/O error"), and not inappropriate for a communictions failure.

That's a nice coincidence, but it's actually an OpenSSL-specific code.
Also, there's a bug in the current patch, the right value should be 1
(SSL_ERROR_SSL) not 5.

That said, I remember there's legacy code doing things like:
    except SSLError as e:
        if e.args[0] == SSL_ERROR_WANT_READ: ...

so we can't ditch the errno, although in 3.3 you would write:
    except SSLWantReadError: ...

Regards

Antoine.


More information about the Python-Dev mailing list