由于某种原因,该程序会打印以下警告:
Task exception was never retrieved
future: <Task finished coro=<coro() done, defined at /usr/lib64/python3.4/asyncio/coroutines.py:139> exception=SystemExit(2,)>
即使明确检索并传播了异常,当caught SystemExit!
打印到终端时,进程状态代码变为2。
Python 2和trollius也是如此。
我错过了什么吗?
#!/usr/bin/env python3
import asyncio
@asyncio.coroutine
def comain():
raise SystemExit(2)
def main():
loop = asyncio.get_event_loop()
task = loop.create_task(comain())
try:
loop.run_until_complete(task)
except SystemExit:
print("caught SystemExit!")
raise
finally:
loop.close()
if __name__ == "__main__":
main()
答案 0 :(得分:7)
SystemExit
似乎是一个特例。例如,如果您举起并抓住Exception
,则不会看到任何错误。
解决这个问题的方法似乎是使用Task.exception()
手动检索异常:
import asyncio
@asyncio.coroutine
def comain():
raise SystemExit(2)
def main():
loop = asyncio.get_event_loop()
task = loop.create_task(comain())
try:
loop.run_until_complete(task)
except SystemExit:
print("caught SystemExit!")
task.exception()
raise
finally:
loop.close()
if __name__ == "__main__":
main()
修改强>
实际上,所有BaseException
子类都会以这种方式运行。
答案 1 :(得分:0)
我认为这是因为SystemExit
和KeyboardInterrupt
是不同的情况。例如,正常Exception
不会导致相同的问题。
您可以将comain
协程链接到另一个协程中以消耗这样的异常:
#!/usr/bin/env python3
import asyncio
@asyncio.coroutine
def comain():
raise SystemExit(2)
@asyncio.coroutine
def another():
try:
yield from comain()
except SystemExit:
print ("consumed")
def main():
loop = asyncio.get_event_loop()
task = loop.create_task(another())
try:
loop.run_until_complete(task)
except SystemExit:
print("caught SystemExit!")
raise
finally:
loop.close()
if __name__ == "__main__":
main()
此处 - 我正在调用another()
而不是comain()
而在another()
内我正在处理来自comain()
的异常。