zid*_*sal 7 python try-catch python-asyncio
所以我有一个事件循环,这将是run_until_complete我的accept_connection方法
@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))
Run Code Online (Sandbox Code Playgroud)
我的handle_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!")
Run Code Online (Sandbox Code Playgroud)
最后我的handle_read_from_connection(目前)看起来像这样:
@asyncio.coroutine
def handle_read_from_connection(self):
raise PacketException("hello")
Run Code Online (Sandbox Code Playgroud)
因此,此方法应始终引发错误并按下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
Run Code Online (Sandbox Code Playgroud)
有谁知道这里发生了什么?为什么尝试捕捉不起作用?我怎样才能得到它以便我们能够发现这些错误
您需要使用以下返回的值asyncio.wait():
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()
Run Code Online (Sandbox Code Playgroud)
got exception
Run Code Online (Sandbox Code Playgroud)
当前的实现asyncio.coroutine假设如果一个函数不是一个生成器(就像你的情况一样),那么它返回一个Future,因此它应该被转换为一个生成器,因此调用raise_exception()不会引发异常,因为它只是创建生成器对象(协程).
然后asyncio.wait()产生它,并完成一些等价物future.set_exception(exception).
为了避免你看到的错误输出; 您需要通过调用future.result()或future.exception()直接使用异常.