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

Zope 5中Python脚本捕获异常后如何记录错误至error_log并返回JSON

解决Zope脚本返回JSON同时记录异常到error_log的问题

下面是几个经过验证的可行方案,针对受限Python环境、无法调用raising()方法以及需要返回JSON的需求:

方案1:直接调用站点内置的error_log对象

Zope站点默认自带error_log对象,不需要额外导入模块,直接获取并调用其raising()方法即可,这是最简便的方式:

import sys
import json

try:
    # 替换为你的业务逻辑代码
    your_business_logic()
    response = {"status": "success", "data": "操作完成"}
except Exception as e:
    # 获取站点根目录下的error_log
    error_log = context.getSite().error_log
    # 传入sys.exc_info()返回的异常三元组(类型、实例、回溯)
    error_log.raising(sys.exc_info())
    # 构造错误JSON响应
    response = {"status": "error", "message": str(e)}
finally:
    # 确保无论成功失败都返回JSON
    return json.dumps(response)

权限配置提示

如果受限脚本提示无权限访问error_log,进入ZMI的Security > Python Script Permissions,将Products.SiteErrorLog.SiteErrorLog.SiteErrorLog添加到允许的类列表中,同时确保当前脚本的执行角色拥有error_log的访问权限。

方案2:通过Zope组件工具获取错误日志

如果直接调用error_log对象有问题,可以用Zope的组件接口来获取日志工具,适合更复杂的站点结构:

import sys
import json
from zope.component import getUtility
from Products.SiteErrorLog.interfaces import ISiteErrorLog

try:
    # 业务代码
    response = {"status": "success", "data": "结果数据"}
except Exception as e:
    # 通过接口获取错误日志实例
    error_log = getUtility(ISiteErrorLog)
    error_log.raising(sys.exc_info())
    response = {"status": "error", "message": str(e)}
finally:
    return json.dumps(response)

方案3:修复外部方法的调用问题

你之前尝试的外部方法没生效,大概率是没有正确获取站点的error_log或者参数传递错误。以下是正确的外部方法实现:

  1. 创建外部方法的Python文件(比如site_error_logger.py):
import sys

def log_exception(context, exc_info):
    # 确保获取到站点根的error_log
    site = context.getSite()
    error_log = site.error_log
    # 传入异常三元组记录错误
    error_log.raising(exc_info)
    # 返回错误信息模板,由调用脚本转为JSON
    return {"status": "error", "message": str(exc_info[1])}
  1. 在ZMI中添加外部方法:绑定到站点根,ID设为log_exception,指向上述文件的log_exception函数。

  2. 在受限Python脚本中调用:

import sys
import json

try:
    # 业务逻辑
    response = {"status": "success"}
except Exception as e:
    # 调用外部方法记录错误
    error_resp = context.log_exception(sys.exc_info())
    response = error_resp
finally:
    return json.dumps(response)

核心注意事项

  • 必须传递sys.exc_info()返回的三元组给raising()方法,不能直接传入异常对象,否则日志不会被正确记录。
  • 不要在except块中使用raise,这会直接终止脚本,导致无法返回JSON;手动记录错误后直接构造响应即可。
  • 如果context.getSite()无法获取站点根,可以尝试用context.aq_inner.aq_parent逐层向上遍历,直到找到包含error_log的对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:47:39