简体   繁体   English

Python:Aioimaplib捕获异常

[英]Python: Aioimaplib catch exceptions

im trying to check multiple imap login informations asynchronously with aioimaplib. 我试图与aioimaplib异步检查多个imap登录信息。 This code works as long as the imap servers are reachable and / or the clients don't time out. 只要imap服务器可访问和/或客户端不超时,此代码就起作用。

What is the correct way to catch the exceptions? 捕获异常的正确方法是什么?

Example exception: 示例异常:

ERROR:asyncio:Task exception was never retrieved future: <Task finished coro=<BaseEventLoop.create_connection() done, defined at G:\WinPython-3.5.4\python-3.5.4.amd64\lib\asyncio\base_events.py:679> exception=TimeoutError(10060, "Connect call failed ('74.117.114.100', 993)")>

Code: 码:

account_infos = [
    # User            Password     Server
    ('user1@web.com', 'password1', 'imap.google.com'),
    ('user2@web.com', 'password2', 'imap.yandex.com'),
    ('user3@web.com', 'password3', 'imap.server3.com'),
]


class MailLogin:
    def __init__(self):
        self.loop = asyncio.get_event_loop()
        self.queue = asyncio.Queue(loop=self.loop)
        self.max_workers = 2

    async def produce_work(self):
        for i in account_infos:
            await self.queue.put(i)
        for _ in range(max_workers):
            await self.queue.put((None, None, None))

    async def worker(self):
        while True:
            (username, password, server) = await self.queue.get()
            if username is None:
                break

            while True:
                try:
                    s = IMAP4_SSL(server)
                    await s.wait_hello_from_server()
                    r = await s.login(username, password)
                    await s.logout()
                    if r.result != 'NO':
                        print('Information works')
                except Exception as e:
                    # DOES NOT CATCH
                    print(str(e))
                else:
                    break

    def start(self):
        try:
            self.loop.run_until_complete(
                asyncio.gather(self.produce_work(), *[self.worker() for _ in range(self.max_workers)],
                               loop=self.loop, return_exceptions=True)
            )
        finally:
            print('Done')


if __name__ == '__main__':
    MailLogin().start()

There are several ways to do this but the TimeoutError is probably caught in your except . 几种方法可以执行此操作,但您的except可能捕获了TimeoutError You don't see it because str(e) is an empty string. 您看不到它,因为str(e)是一个空字符串。

You can see the stacks enabling debug mode of asyncio. 您可以看到启用了异步调试模式的堆栈。

First, you can catch the exception as you did: 首先,您可以像以前那样捕获异常:

async def fail_fun():
    try:
        imap_client = aioimaplib.IMAP4_SSL(host='foo', timeout=1)
        await imap_client.wait_hello_from_server()
    except Exception as e:
        print('Exception : ' + str(e))

if __name__ == '__main__':
    get_event_loop().run_until_complete(fail_fun())

Second, you can catch the exception at run_until_complete 其次,您可以在run_until_complete处捕获异常

async def fail_fun():
    imap_client = aioimaplib.IMAP4_SSL(host='foo', timeout=1)
    await imap_client.wait_hello_from_server()

if __name__ == '__main__':
    try:
        get_event_loop().run_until_complete(fail_fun())
    except Exception as e:
        print('Exception : ' + str(e))

The connection is established wrapping the loop.create_connection coroutine with create_task : we wanted to establish the connection in the IMAP4 constructor and __init__ should return None . 建立连接,将loop.create_connection协程与create_task包裹在一起:我们想在IMAP4构造函数中建立连接,并且__init__ 应该返回None

So if your host has a wrong value, you could test it before, or wait for the timeout : 因此,如果主机的值错误,则可以在之前对其进行测试,或者等待超时:

socket.gaierror: [Errno -5] No address associated with hostname

if a host is not responding before the timeout, you can raise the timeout. 如果主机在超时之前没有响应,则可以提高超时时间。 And if the connection is lost during the connection, you can add a connection lost callback in the IMAP4 constructor. 而且,如果在连接过程中连接丢失,则可以在IMAP4构造函数中添加连接丢失回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM