如果协程引发asyncio异常,如何关闭循环并显示错误? [英] How to shutdown the loop and print error if coroutine raised an exception with asyncio?

查看:112
本文介绍了如果协程引发asyncio异常,如何关闭循环并显示错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有几个协程在一个循环中运行。如何使它们中的某些异常失败而导致整个程序因异常而失败?因为现在,除非我使用日志记录级别 DEBUG,否则asyncio甚至不会从协程中输出错误消息。

 从asyncio导入get_event_loop,睡眠


异步定义c(sleep_time = 2,fail = False):
print('c',sleep_time,失败)
如果失败:
引发Exception('fail')
而True:
print('doing stuff')
await sleep(sleep_time)



loop = get_event_loop()
loop.create_task(c(sleep_time = 10,fail = False))
loop.create_task(c(fail = True))
loop.run_forever( )


解决方案

一种优雅的方法是使用错误处理api。 / p>

https://docs.python.org/3/library/asyncio-eventloop.html#error-handling-api



示例:

 导入异步


异步def run_division( a,b):
等待asyncio.sleep(2)
返回a / b


def custom_exception_handler(loop,context):
#first ,使用默认处理程序
循环处理.default_exception_handler(context)

exception = context.get('exception')
if isinstance(exception,ZeroDivisionError):
打印(上下文)
loop.stop()

loop = asyncio.get_event_loop()

#设置自定义处理程序
loop.set_exception_handler(custom_exception_handler)
loop.create_task(run_division(1,0))
loop.run_forever()


Suppose I have a few coroutines running in a loop. How to make so that if some of them failed with exception the whole program would fail with this exception? Because right now asyncio doesn't even prints the error messages from coroutines unless I use logging level "DEBUG".

from asyncio import get_event_loop, sleep


async def c(sleep_time=2, fail=False):
    print('c', sleep_time, fail)
    if fail:
        raise Exception('fail')
    while True:
        print('doing stuff')
        await sleep(sleep_time)



loop = get_event_loop()
loop.create_task(c(sleep_time=10, fail=False))
loop.create_task(c(fail=True))
loop.run_forever()

解决方案

A graceful way is using error handling api.

https://docs.python.org/3/library/asyncio-eventloop.html#error-handling-api

Example:

import asyncio


async def run_division(a, b):
    await asyncio.sleep(2)
    return a / b


def custom_exception_handler(loop, context):
    # first, handle with default handler
    loop.default_exception_handler(context)

    exception = context.get('exception')
    if isinstance(exception, ZeroDivisionError):
        print(context)
        loop.stop()

loop = asyncio.get_event_loop()

# Set custom handler
loop.set_exception_handler(custom_exception_handler)
loop.create_task(run_division(1, 0))
loop.run_forever()

这篇关于如果协程引发asyncio异常,如何关闭循环并显示错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆