计划动作(ir.cron)按计划在服务端执行 Python 代码。Odoo 19 会在 cron 记录上跟踪失败,理解这套机制,定时任务才能更稳定。
1. 内置失败处理
默认大致行为:
- 每条 cron 字段包含 failure_count、first_failure_date
- 发生异常时:_callback() 事务回滚、再次抛出异常,并标记本次失败
- 7 天内连续失败 5 次 → 自动停用 cron,并调用 _notify_admin()
- 成功执行一次,failure_count 重置为 0
2. 方法一:在 cron 方法内 try/except
可恢复错误捕获记录;不可恢复错误继续 raise,交由 Odoo 累加失败计数。
for order in orders:
try:
order._sync_to_external_system()
except ConnectionError as e:
_logger.warning("Sync failed for %s: %s. Skipping.", order.name, e)
continue
except Exception as e:
_logger.error("Unexpected error for %s: %s", order.name, e, exc_info=True)
raise
适用场景:单条数据失败不拖垮整批任务;严重错误仍然计入 cron 失败统计。
3. 方法二:重写 _notify_admin
默认 _notify_admin 仅输出日志。继承 ir.cron,可在任务因多次失败被停用后,推送邮件、内部消息、Webhook、Slack 告警。
参考文件:models/ir_cron.py、data/mail_template_data.xml
适用场景:需要在运维人员手动发现 cron 被停用之前主动告警。
4. 方法三:读取失败字段做分支逻辑
在任务代码中读取 failure_count / first_failure_date,触发安全模式(仅诊断、记录日志,不执行写库、发信、调用外部API等高危操作)。
if cron and cron.failure_count >= 3:
# 安全模式:只报告,不执行业务动作
return
# 正常模式:继续处理业务
适用场景:连续多次失败后继续写库风险较高;需要自定义降级策略。
5. 实践提示
- 只捕获明确可恢复的异常;其余异常交给框架处理
- 邮件模板等 xml 数据建议设置 noupdate="1"
- 根因修复后,手动重新启用 cron,任务运行成功后会自动清零 failure_count