从未检索到Python-asyncio-Task异常

从未检索到Python-asyncio-Task异常,python,asynchronous,python-asyncio,coroutine,Python,Asynchronous,Python Asyncio,Coroutine,说明:(简化) 我有两项任务 在每个任务中,我有3个协同程序 来自第一个任务的2个协同路由失败。(模拟) 在处理任务结果时,我收到一条“从未检索到任务异常”消息 我相信这是因为该任务中两个失败的协同路由中只有一个例外被处理 如何处理任务内两个协同路由的异常和/或避免“从未检索到任务异常”消息 代码:(简化) 输出:(简化) 从未检索到任务异常 未来: 回溯(最近一次呼叫最后一次): 下载文件“D:/myscript.py”,第4行 打开(文件名为“w”)作为f: OSError:[Errno

说明:(简化)

  • 我有两项任务
  • 在每个任务中,我有3个协同程序
  • 来自第一个任务的2个协同路由失败。(模拟)
  • 在处理任务结果时,我收到一条“从未检索到任务异常”消息
  • 我相信这是因为该任务中两个失败的协同路由中只有一个例外被处理
  • 如何处理任务内两个协同路由的异常和/或避免“从未检索到任务异常”消息
代码:(简化)

输出:(简化)

从未检索到任务异常 未来: 回溯(最近一次呼叫最后一次): 下载文件“D:/myscript.py”,第4行 打开(文件名为“w”)作为f: OSError:[Errno 22]无效参数:'*'
如果希望收集异常而不是引发异常,也可以在
coro
中使用
asyncio.gather(return\u exceptions=True)
。例如:

import asyncio

async def download(data):
    if data in ['b', 'c']:
        1/0    # simulate error
    return 42  # success

async def coro(data_list):
    coroutines = [download(data) for data in data_list]
    return await asyncio.gather(*coroutines, return_exceptions=True)

async def main():
    task1 = asyncio.create_task(coro(["a", "b", "c"]))
    task2 = asyncio.create_task(coro(["d", "e", "f"]))
    return await asyncio.gather(task1, task2, return_exceptions=True)

print(asyncio.run(main()))
这将打印:

[[42, ZeroDivisionError('division by zero'), ZeroDivisionError('division by zero')], [42, 42, 42]]

你能在公共URL上重复同样的问题吗,这样我们就可以尝试并复制它了?@user4815162342-谢谢。是的,我已经大大简化了代码并使其可复制。还将问题缩小到仅异步IO。请参考编辑后的问题。可能您简化得太过分了,因为这是一个完全不同的错误-Windows不喜欢文件名中的
*
字符,并且文件名globbing不能与Python的
open()
一起使用。我故意添加了不正确的文件名
*
,以模拟任务异常并查看如何检索所有异常。
import asyncio

async def download(data):
    if data in ['b', 'c']:
        1/0    # simulate error
    return 42  # success

async def coro(data_list):
    coroutines = [download(data) for data in data_list]
    return await asyncio.gather(*coroutines, return_exceptions=True)

async def main():
    task1 = asyncio.create_task(coro(["a", "b", "c"]))
    task2 = asyncio.create_task(coro(["d", "e", "f"]))
    return await asyncio.gather(task1, task2, return_exceptions=True)

print(asyncio.run(main()))
[[42, ZeroDivisionError('division by zero'), ZeroDivisionError('division by zero')], [42, 42, 42]]