You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确区分并捕获asyncvnc中的异步通信与库内部异常

区分asyncvnc库的通信异常与库自身异常

我用asyncvnc库和VNC服务器交互,需求是忽略所有通信类错误(连接超时、意外断开、收发数据失败等),只抛出库自身相关的异常。目前的异常判断逻辑太粗糙,示例代码如下:

result = False
try:
    async with connect(host=host, port=port) as client:
        client: Client = client

        screen_first = await _get_screen(client)
        _send_keystroke_combination(client, ('ctrl', 'alt', 'del'))
        await asyncio.sleep(screen_delay / 1000)
        screen_second = await _get_screen(client)

        result = bool((screen_first != screen_second).any())

except Exception as e:
    er = (str(e.__class__) + str(e.args)).lower()
    if "password" in er or "connect" in er or isinstance(e, (EnvironmentError, ValueError)) or str(e.__class__.__name__) in asyncio_exceptions:
        """
        ..note::
            This is not shitcode, it's just that there is no general exception in the library
            Ok, this is shitcode, but I didn't find a proper way to except the server connection or timeout error >:(
        """
        pass
    else:
        raise e

return result

我不认可当前的实现方式,但不知道怎么合理区分通信类错误和其他异常。这个库主要抛出ValueError,但还有asyncio超时异常、OSError等通信相关异常。


优化方案

1. 明确需要忽略的通信异常范围

先把通信相关的异常类型和场景整理清楚:

  • asyncio网络/超时异常:asyncio.TimeoutError、asyncio.CancelledError
  • 系统级网络错误:OSError及其所有子类(比如ConnectionRefusedError、ConnectionResetError、TimeoutError等)
  • 库中与连接/密码相关的ValueError(比如密码错误、连接参数无效)

2. 重构异常捕获逻辑

直接针对明确的异常类型捕获,配合精准的异常信息判断,替代模糊的字符串匹配:

import asyncio

result = False
# 定义需要忽略的通信相关异常类型
COMMUNICATION_EXCEPTIONS = (asyncio.TimeoutError, asyncio.CancelledError, OSError)

try:
    async with connect(host=host, port=port) as client:
        client: Client = client

        screen_first = await _get_screen(client)
        _send_keystroke_combination(client, ('ctrl', 'alt', 'del'))
        await asyncio.sleep(screen_delay / 1000)
        screen_second = await _get_screen(client)

        result = bool((screen_first != screen_second).any())

except COMMUNICATION_EXCEPTIONS:
    # 直接忽略所有明确的通信类异常
    pass
except ValueError as e:
    # 只忽略与连接、密码相关的ValueError,其他ValueError抛出
    err_msg = str(e).lower()
    if "password" in err_msg or "connect" in err_msg:
        pass
    else:
        raise e
# 剩下的所有异常直接抛出,确保库自身逻辑错误不被吞掉
except Exception as e:
    raise e

return result

3. 方案优势

  • 避免了原代码中模糊的字符串拼接匹配,逻辑更清晰可靠
  • 明确区分了通信类异常和库内部逻辑异常,不会误吞重要错误
  • 代码结构更规整,后续维护时容易调整异常范围

内容的提问来源于stack exchange,提问作者Noberto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 21:40:10