捕获asyncio.ensure_future中的错误

10

我有这段代码:

try:
    asyncio.ensure_future(data_streamer.sendByLatest())
except ValueError as e:
    logging.debug(repr(e))

data_streamer.sendByLatest() 可能会引发一个 ValueError,但是它没有被捕获。

1个回答

13

ensure_future - 只是创建一个 Task 并立即返回。您需要等待创建的任务以获取其结果(包括引发异常的情况):

import asyncio


async def test():
    await asyncio.sleep(0)
    raise ValueError('123')


async def main():    
    try:
        task = asyncio.ensure_future(test())  # Task aren't finished here yet 
        await task  # Here we await for task finished and here exception would be raised 
    except ValueError as e:
        print(repr(e))


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

输出:

ValueError('123',)

如果您创建任务后不打算立即等待它完成,可以稍后等待它(以了解它的完成情况):

async def main():    
    task = asyncio.ensure_future(test())
    await asyncio.sleep(1)
    # At this moment task finished with exception,
    # but we didn't retrieved it's exception.
    # We can do it just awaiting task:
    try:
        await task  
    except ValueError as e:
        print(repr(e)) 

输出结果相同:

ValueError('123',)

谢谢。您是否也知道如何使用call_soon_threadsafe()捕获异常? - Marco Sulla
@MarcoSulla 抱歉,我不知道。我看到的一种方法是使用包装器来处理回调中的异常:http://pastebin.com/rNyTWMBk 但我不知道这是否是常用的方法。 - Mikhail Gerasimov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接