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

为何Requests的Session.get()超时抛出ConnectionError而非Timeout异常?

为什么requests的GET请求超时抛出ConnectionError而非Timeout?

这个问题其实和你使用的requests版本直接相关,让我给你拆解清楚来龙去脉:

1. requests中两种超时场景的差异

requests的timeout参数实际管控两类超时情况:

  • 连接超时:客户端尝试与服务器建立TCP连接时的超时(比如服务器地址不可达、拒绝连接),这类超时在几乎所有requests版本里都会抛出requests.exceptions.Timeout。
  • 读取超时:TCP连接已经成功建立,但服务器迟迟没有返回响应数据的超时(也就是你回溯里看到的Read timed out),这个行为在不同requests版本里有明显区别:
    • 在requests < 2.21.0的旧版本中,读取超时会被包装成ConnectionError抛出;
    • 在requests >= 2.21.0的新版本中,读取超时会抛出requests.exceptions.ReadTimeout(它是Timeout的子类),这就和官方文档描述的行为完全一致了。

你的错误日志明确显示是Read timed out,说明是读取阶段的超时,而你当前使用的requests版本刚好是旧版,所以才会抛出ConnectionError而非预期的Timeout。

2. 可行的解决方案

针对这个问题,你有两种处理思路:

方案一:升级requests版本

直接升级到最新稳定版,就能让读取超时抛出Timeout类异常,和文档行为对齐:

pip install --upgrade requests

方案二:兼容旧版本的异常捕获

如果因为环境限制无法升级,你可以同时捕获Timeout和ConnectionError,并通过异常信息判断是否属于读取超时:

from requests.exceptions import Timeout, ConnectionError

with requests.Session() as rs:
    try:
        with rs.get(url, params={}, headers={}, auth=self.auth, verify=self.ssl_verify, timeout=30) as r:
            # 处理响应逻辑
            pass
    except Timeout:
        # 处理连接超时场景
        print("建立连接时超时")
    except ConnectionError as e:
        if "Read timed out" in str(e):
            # 处理读取超时场景
            print("等待响应时读取超时")
        else:
            # 处理其他连接错误(比如DNS解析失败、连接被拒绝等)
            print(f"发生连接错误:{e}")

额外补充:你可以把timeout参数拆成元组,分别设置连接超时和读取超时,比如timeout=(5, 30),表示5秒内必须建立连接,30秒内必须拿到响应数据,这样能更精准地管控不同阶段的超时情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 11:47:38