如何让初始连接函数尝试多URL失败后由外层循环捕获异常?
问题分析
你的代码逻辑存在两个核心问题:
- Spot客户端初始化不触发实际连接:创建
Spot对象时仅完成参数配置,不会发起真实HTTP请求,因此initial_connect内部的try-except无法捕获连接错误——这类错误只会在调用客户端API方法(如查询行情、提交订单)时才会抛出,直接跳转到外层的try-except。 - 空except块过于宽泛:未明确捕获连接类异常,可能掩盖其他错误;同时第二个URL若也连接失败,异常会直接向外抛出,没有在内部完成重试逻辑的闭环。
解决方案
修改initial_connect函数,在创建客户端后执行一个轻量API请求(比如获取服务器时间)验证连接有效性,明确捕获连接异常,按顺序重试两个URL,仅当所有URL都失败时才向外抛出异常。
修改后的代码
1. 调整initial_connect函数
def initial_connect(self): # 定义待尝试的API URL列表 api_urls = ['https://api4.binance.com', 'https://api2.binance.com'] for url in api_urls: try: client = Spot(key=self.api_key, secret=self.secret_key, base_url=url) # 执行轻量请求触发真实连接,验证有效性 client.time() return client except ConnectionError: # 捕获连接错误,继续尝试下一个URL continue # 所有URL均连接失败,抛出异常交由外层处理 raise ConnectionError("所有Binance API URL连接均失败")
2. 外层调用逻辑(无需大幅修改)
for trade in trades: try: client = initial_connect() # 此处执行你的业务逻辑,如client.get_ticker()等 except Exception as e: error_log(str(e))
关键说明
- 添加连接验证:通过
client.time()触发真实HTTP请求,确保连接错误能在初始化阶段被捕获,而非等到后续业务逻辑执行时才报错。 - 明确捕获异常:仅捕获
ConnectionError(或更具体的requests.exceptions.ConnectionError,若底层使用requests库),避免掩盖API密钥错误等其他问题。 - 循环重试机制:用列表管理备用URL,后续新增备用地址只需修改列表,逻辑更简洁易维护。
- 主动抛出异常:所有URL失败后主动抛出异常,确保外层错误日志能准确记录故障情况。
内容的提问来源于stack exchange,提问作者Alireza Aghdaee
相关产品推荐
相关产品推荐

