pythonexceptionpython-3.3try-exceptpoplib

Printing passed bytes from Exception


This seems to be the code for the poplib.error_proto.

class error_proto(Exception): pass

It just passes the bytes from the POP response in the exception. What I would like to do is catch any exception, take those bytes, use .decode('ascii') on them, and print them as a string. I've written my own test setup like so:

class B(Exception): pass

def bex(): raise B(b'Problem')

try:
    bex()
except B as err:
    print(err.decode('ascii'))

I've tried replacing the last line with:

    b = bytes(err)
    print(b.decode('ascii'))

But to no avail. Is this possible and if so, how would I implement this?

UPDATE: Though, as falsetru points out, the documentation says results are returned as strings, this is not the case:

>>> p = poplib.POP3('mail.site.com')
>>> p.user('skillian@site.com')
b'+OK '
>>> p.pass_('badpassword')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python33\lib\poplib.py", line 201, in pass_
    return self._shortcmd('PASS %s' % pswd)
  File "C:\Python33\lib\poplib.py", line 164, in _shortcmd
    return self._getresp()
  File "C:\Python33\lib\poplib.py", line 140, in _getresp
    raise error_proto(resp)
poplib.error_proto: b'-ERR authorization failed  Check your server settings.'
>>>

Solution

  • According to poplib.error_proto documentation:

    Exception raised on any errors from this module (errors from socket module are not caught). The reason for the exception is passed to the constructor as a string.

    So, you don't need to decode it.


    UPDATE It seems like the documentation does not match the actual implementation.

    You can access the arguments passed to the exception constructor using args attribute.

    p = poplib.POP3('mail.site.com')
    try:
        p.user('skillian@site.com')
        p.pass_('badpassword')
    except poplib.error_proto as e:
        print(e.args[0].decode('ascii')) # `'ascii'` is not necessary.