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

如何延迟抛出urllib3的NewConnectionError异常且不修改源码?

解决方案

方法1:猴子补丁捕获暂存异常

通过猴子补丁改写urllib3的连接方法,捕获NewConnectionError并暂存,待需要时再抛出,无需修改库源码:

import urllib3
from urllib3.exceptions import NewConnectionError

# 全局列表存储暂存的异常
pending_exceptions = []

# 保存原始连接方法
original_connect = urllib3.connection.HTTPConnection.connect

def patched_connect(self):
    try:
        original_connect(self)
    except NewConnectionError as e:
        # 将异常存入全局列表,不立即抛出
        pending_exceptions.append(e)
        # 若需让后续代码正常执行,可根据业务场景构造模拟响应
        # 例如:如果使用requests,可返回一个假的响应对象(需适配调用逻辑)

# 应用补丁,需确保在requests等依赖库导入前执行
urllib3.connection.HTTPConnection.connect = patched_connect

# 在合适时机抛出暂存的异常
if pending_exceptions:
    # 可选择抛出第一个异常,或遍历抛出全部
    raise pending_exceptions[0]

方法2:上下文管理器包裹代码块

若明确哪些代码会触发异常,用上下文管理器捕获并暂存:

from urllib3.exceptions import NewConnectionError

pending_exceptions = []

class HoldConnectionErrors:
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is NewConnectionError:
            pending_exceptions.append(exc_val)
            return True  # 标记异常已处理,阻止向上抛出
        return False

# 使用示例
with HoldConnectionErrors():
    # 放入可能触发拒绝连接异常的代码
    import requests
    requests.get("http://localhost:9999")

# 后续需要时抛出异常
if pending_exceptions:
    raise pending_exceptions[0]

关键注意点

  • 猴子补丁必须在requests等依赖urllib3的库导入前执行,否则补丁不会生效。
  • 若后续代码依赖请求成功的结果,需构造适配业务的模拟响应,避免逻辑崩溃。
  • 可在暂存异常时额外记录请求URL、时间等上下文信息,方便后续排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:12:46