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

Python2.6中如何处理异常以保障程序持续运行?

让Python2.6脚本在请求超时后持续运行的解决方案

你的问题核心在于异常捕获的范围错误:当前的try-except包裹了整个监听循环(notifier.loop()),当单个文件处理中的网络请求抛出超时异常时,会直接跳出整个循环,导致程序终止。正确的做法是把异常捕获放在单个文件请求的逻辑内部,这样即使某次请求失败,监听循环依然能继续运行。

具体修改步骤

1. 聚焦请求逻辑的异常处理

你的ModHandler类是处理文件事件的核心(当目录有新文件关闭时触发),需要把网络请求的代码从ModHandler的处理方法中(比如process_default或自定义方法)单独用try-except包裹,确保单个请求的错误不会影响全局循环。

2. 修改请求代码的异常捕获

把原来的请求逻辑改成下面这样,在请求内部针对性捕获错误,写入日志后继续执行:

# 假设这段代码在ModHandler的文件处理方法中
def process_default(self, event):
    image_file_path = event.pathname
    try:
        with open(image_file_path, 'rb') as image_file:
            encoded_string = base64.b64encode(image_file.read())
            values = dumps({ 'image_data':encoded_string, 'requestCode':'111' })
            headers = {"Content-Type": "application/json"}
            # 注意URL补全http://前缀,避免请求错误
            request = Request("http://xx.xxx.xx.xxx/api/carplate_service", data=values, headers=headers)
            response = urlopen(request, timeout=60)
            # 如需处理响应,可在此添加逻辑
    except urllib2.URLError as e:
        # 捕获超时等URL相关错误
        self._log_error(e, sys.exc_info())
    except IOError as e:
        # 捕获文件读取类错误
        self._log_error(e, sys.exc_info())
    except Exception as e:
        # 兜底捕获其他意外错误
        self._log_error(e, sys.exc_info())

# 新增复用的日志记录方法
def _log_error(self, error, exc_info):
    exc_type, exc_obj, exc_tb = exc_info
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
    with open("error.log", "a") as text_file:
        log_msg = "{0} [{1} - {2}] : {3} - {4}\n".format(
            time.strftime("%Y-%m-%d %H:%M:%S"),
            exc_tb.tb_lineno,
            fname,
            str(exc_type),
            str(error)
        )
        text_file.write(log_msg)

3. 调整外层异常处理的职责

原来的外层try-except可以保留,但只用来捕获监听循环本身的致命错误(比如初始化失败、监听目录不存在等),不再处理单个请求的错误:

try:
    ip = sys.argv[1]
    histId = int(sys.argv[2])
    handler = ModHandler()
    wm = pyinotify.WatchManager()
    notifier = pyinotify.Notifier(wm, handler)
    watch_path = './' + ip + '/'
    
    # 提前检查目录是否存在,避免初始化阶段失败
    if not os.path.isdir(watch_path):
        raise IOError(f"监听目录 {watch_path} 不存在或不是合法目录")
    
    wdd = wm.add_watch(watch_path, pyinotify.IN_CLOSE_WRITE)
    notifier.loop()
except BaseException as e:
    with open("error.log", "a") as text_file:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        text_file.write(
            time.strftime("%Y-%m-%d %H:%M:%S") + " [" + str(exc_tb.tb_lineno) + " - " + fname + "] : " + str(exc_type) + " - " + str(e) + "\n"
        )

额外优化建议

  • 增加重试机制:凌晨的超时大概率是服务端维护或网络波动,可以给请求加3次以内的重试,间隔2秒:
    max_retries = 3
    retry_count = 0
    success = False
    while retry_count < max_retries and not success:
        try:
            response = urlopen(request, timeout=60)
            success = True
        except urllib2.URLError as e:
            retry_count += 1
            time.sleep(2)
            if retry_count == max_retries:
                self._log_error(e, sys.exc_info())
    
  • 日志补充上下文:可以在错误日志中加入当前处理的文件名,方便后续排查具体是哪个文件的请求失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:43:55