无法捕获WebSocket通信中的asyncio.IncompleteReadError异常求助
无法捕获WebSocket通信中的asyncio.IncompleteReadError异常求助
看起来你遇到的问题是websockets库已经把底层的IncompleteReadError包装成ConnectionClosedError抛出了,所以你单独写的except asyncio.IncompleteReadError:永远不会被触发——这也是为什么你在debug栈里能看到IncompleteReadError作为异常的直接原因,但实际抛出的顶层异常是ConnectionClosedError。
咱们来拆解一下具体原因:
- 当websocket连接突然中断(比如服务器崩溃、网络断开),底层的
recv()会抛出IncompleteReadError,但websockets库为了统一连接关闭类的异常处理,会把这个底层异常包装成ConnectionClosedError再抛出来。 - 你用
asyncio.wait_for()包裹websocket.recv(),它只会传递上层抛出的ConnectionClosedError,而不会暴露底层的IncompleteReadError给你的捕获块。
那怎么解决呢?其实你可以调整异常捕获的逻辑,不需要单独抓IncompleteReadError,而是在ConnectionClosedError的捕获块里区分异常原因,或者直接统一处理所有连接关闭的情况(毕竟你的核心需求是连接丢失时停止脚本)。
修改后的代码可以参考这样:
try: # 持续接收服务器消息 while True: response = await asyncio.wait_for(websocket.recv(), timeout=1) print(color + response + colorama.Style.RESET_ALL) except asyncio.TimeoutError: print("No response from server") if must_restart: return 'restart' except websockets.exceptions.ConnectionClosedError as e: # 可以根据异常原因区分处理 if isinstance(e.__cause__, asyncio.IncompleteReadError): print("连接异常中断:读取到不完整的数据") else: print("连接已正常关闭") # 这里直接return,让脚本停止执行 return
这样调整后,不管是正常关闭连接还是异常断开(包括触发IncompleteReadError的情况),都能被正确捕获并退出循环,解决你脚本不停止的问题。
另外提个小细节:Python里判断布尔值不用== True,直接写if must_restart:就可以啦,更简洁。
备注:内容来源于stack exchange,提问作者Stardaz
相关产品推荐
相关产品推荐

