Catching imaplib exception (using IMAPClient package) in Python

I am using external library IMAPClient. When login fails, I see this error:imaplib.error: [AUTHENTICATIONFAILED] Authentication failed.

When I try except imaplib.error:

I get:AttributeError: 'module' object has no attribute 'error'

Imaplib documentation says the exception should be IMAP4.error Then why is IMAPClient raising imaplib.error and how to catch it?


source to share

2 answers

The error message you see:

imaplib.error: [AUTHENTICATIONFAILED] Authentication failed.


describes the error as best he knows it; at the time the exception is thrown, the exception class is named "imaplib.error" because whoever raised it described it that way (more on that later). I poked and I think I found it for you:

Python 2.7.2 (default, Nov 14 2011, 19:37:59) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import imaplib
>>> imaplib.IMAP4.error
<class 'imaplib.error'>


I opened the file and found what looks like an odd exception throwing mechanism. "IMAP4" is a class and "error" is a class defined within the IMAP4 class. Python is not a nest of classes - just class definitions. Therefore, when an object of class "error" exists, it is an object of class "error", which was defined in the scope "imaplib". The fact that the "error" class definition was inside the "IMAP4" lib class definition has nothing to do with Python. On the other hand, in order to describe an object of class "error" before such an object exists, you need to refer to it as imaplib.IMAP4.error so that Python can find the definition of the class you are talking about.

Very confusing, I know, and I really didn't know all of this before I started looking into the matter. Here's a quick example:

Python 2.7.2 (default, Nov 14 2011, 19:37:59) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class foo(object):
...   class bar(object):
...     pass
...   def b(self):
...     return bar()
>>> bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'bar' is not defined
<class ''>
>>> foo().bar()
< object at 0x10048dd10>


Basically, you tried to do a very sane thing, but the way the imaplib library handles exception throwing is a little weird, making your life difficult. In short, you must try to catch imaplib.IMAP4.error

and get on with your life.



(Disclaimer: I am the custodian of the IMAPClient)

IMAPClient uses imaplib under the hood, so you see imaplib errors while using it. To simplify things, imaplib exceptions are overlaid on the IMAPClient class. To catch errors from the IMAPClient, you can do something like this:

from imapclient import IMAPClient

    client = IMAPClient(...)
except IMAPClient.Error, err:
    # handle error here



- the base class of the exception (the same as imaplib.IMAP4.error

). There's also AbortError

, and ReadOnlyError


IMAPClient uses these exceptions when it throws errors, so there is only one set of exceptions in your code.



All Articles