未捕获应在asyncio.wait中出错并在try子句中捕获的Python代码

未捕获应在asyncio.wait中出错并在try子句中捕获的Python代码,python,try-catch,python-asyncio,Python,Try Catch,Python Asyncio,因此,我有一个事件循环,它将运行\u直到\u完成我的接受\u连接方法 @asyncio.coroutine def accept_connection(self): assert self.server_socket is not None while True: client, addr = yield from self.loop.sock_accept(self.server_socket) asyncio.async(self.handl

因此,我有一个事件循环,它将
运行\u直到\u完成
我的
接受\u连接
方法

@asyncio.coroutine
def accept_connection(self):
    assert self.server_socket is not None

    while True:
        client, addr = yield from self.loop.sock_accept(self.server_socket)
        asyncio.async(self.handle_connection(client, addr))
我的
handle\u connection
方法如下所示

 def handle_connection(self, client, addr):
     #removed error checking

    while True:
        try:
            yield from asyncio.wait([con.handle_read_from_connection()], timeout=5.0)
        except (AssertionError, PacketException):
            print("Invalid packet detected!")

最后,我的
handle\u read\u from\u connection
(当前)如下所示:

@asyncio.coroutine
def handle_read_from_connection(self):
    raise PacketException("hello")
因此,此方法应始终引发错误并点击try-catch语句的except块并打印检测到的无效数据包。相反,我得到的是一个回溯

future: Task(<handle_read_from_connection>)<exception=PacketException('hello',)>
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 283, in _step
    result = next(coro)
  File "/some_path.py", line 29, in handle_read_from_connection
    raise PacketException("hello")
GameProtocol.GameProtocol.PacketException: hello
future:Task()
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python3.4/asyncio/tasks.py”,第283行,步骤
结果=下一个(coro)
文件“/some_path.py”,第29行,在handle_read_from_connection中
引发PacketException(“hello”)
GameProtocol.GameProtocol.PacketException:您好

有人知道这里发生了什么吗?为什么试抓不起作用?我如何获取它以便捕获这些错误

您需要使用从
asyncio.wait()返回的值

输出
asyncio.coroutine
的当前实现假定,如果函数不是生成器(如您的情况),那么它将返回未来,因此应该将其转换为生成器,因此调用
raise\u exception()
不会引发异常,因为它只创建生成器对象(coroutine)

然后,
asyncio.wait()
将生成它,并完成与
future.set\u exception(exception)
相当的操作


避免您看到的错误输出;您需要通过直接调用
future.result()
future.exception()
来使用异常。

handle\u read\u from\u connection
不是生成器,因为它不包含来自
收益,所以它不是真正的协同程序。尝试通过从
中添加一个
收益率,然后提高收益率来重新构造它。@NedDeily:装饰师已经这样做了。驾车评论到此为止!
import asyncio

class Error(Exception):
    pass

@asyncio.coroutine
def main():
    try:
        done, pending = yield from asyncio.wait([raise_exception()], timeout=1)
        assert not pending
        future, = done # unpack a set of length one
        print(future.result()) # raise an exception or use future.exception()
    except Error:
        print('got exception', flush=True)
    else:
        print('no exception', flush=True)

@asyncio.coroutine
def raise_exception(): # normally it is a generator (yield from)
                       #  or it returns a Future
    raise Error("message")

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
got exception