首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python3.5 Asyncio -防止任务例外从倾倒到标准?

Python3.5 Asyncio -防止任务例外从倾倒到标准?
EN

Stack Overflow用户
提问于 2018-05-05 18:47:14
回答 2查看 2.2K关注 0票数 5

我的程序有一个基于文本的接口(asciimatics模块),它使用异步和discord.py模块,偶尔当我的wifi适配器出现故障时,我会得到这样的异常:

代码语言:javascript
复制
Task exception was never retrieved
future: <Task finished coro=<WebSocketCommonProtocol.run() done, defined at /home/mike/.local/lib/python3.5/site-packages/websockets/protocol.py:428> exception=ConnectionResetError(104, 'Connection reset by peer')>
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "/home/mike/.local/lib/python3.5/site-packages/websockets/protocol.py", line 434, in run
    msg = yield from self.read_message()
  File "/home/mike/.local/lib/python3.5/site-packages/websockets/protocol.py", line 456, in read_message
    frame = yield from self.read_data_frame(max_size=self.max_size)
  File "/home/mike/.local/lib/python3.5/site-packages/websockets/protocol.py", line 511, in read_data_frame
    frame = yield from self.read_frame(max_size)
  File "/home/mike/.local/lib/python3.5/site-packages/websockets/protocol.py", line 546, in read_frame
    self.reader.readexactly, is_masked, max_size=max_size)
  File "/home/mike/.local/lib/python3.5/site-packages/websockets/framing.py", line 86, in read_frame
    data = yield from reader(2)
  File "/usr/lib/python3.5/asyncio/streams.py", line 670, in readexactly
    block = yield from self.read(n)
  File "/usr/lib/python3.5/asyncio/streams.py", line 627, in read
    yield from self._wait_for_data('read')
  File "/usr/lib/python3.5/asyncio/streams.py", line 457, in _wait_for_data
    yield from self._waiter
  File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
    raise self._exception
  File "/usr/lib/python3.5/asyncio/selector_events.py", line 662, in _read_ready
    data = self._sock.recv(self.max_size)
ConnectionResetError: [Errno 104] Connection reset by peer

这个异常不是致命的,尽管如此,程序还是能够重新连接--我想要做的是防止这个异常转储到stdout,并破坏我的文本界面。

我试过使用ensure_future来处理它,但它似乎不起作用。我是不是遗漏了什么:

代码语言:javascript
复制
@asyncio.coroutine
def handle_exception():
    try:
        yield from WebSocketCommonProtocol.run()
    except Exception:
        print("SocketException-Retrying")


asyncio.ensure_future(handle_exception())
#start discord client
client.run(token)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-05 19:48:48

Task exception was never retrieved -实际上不是传播到stdout的异常,而是一条日志消息,警告您在某个任务中从未检索过异常。你可以找到细节这里

我想,在您的情况下,避免此消息的最简单方法是手动从任务中检索异常:

代码语言:javascript
复制
coro = WebSocketCommonProtocol.run()  # you don't need any wrapper
task = asyncio.ensure_future(coro)

try:

    #start discord client
    client.run(token)

finally:

     # retrieve exception if any:
    if task.done() and not task.cancelled():
        task.exception()  # this doesn't raise anything, just mark exception retrieved
票数 5
EN

Stack Overflow用户

发布于 2018-05-09 21:52:38

Mikhail提供的答案是完全可以接受的,但是我意识到它对我来说是行不通的,因为提出异常的任务被深埋在某个模块中,所以试图检索它的异常是很困难的。我发现,如果我只是为异步循环设置一个自定义异常处理程序(循环是由不和谐的客户端创建的):

代码语言:javascript
复制
def exception_handler(loop,context):
   print("Caught the following exception")
   print(context['message'])

client.loop.set_exception_handler(exception_handler)
client.run(token)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50192934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档