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

Twisted框架中LoopingCall遇异常后如何维持脚本持续运行?

解决Twisted LoopingCall异常后停止的问题

你的问题核心在于:Twisted的LoopingCall默认会在任务函数抛出异常(或返回失败的Deferred)时终止整个循环,因为错误会触发LoopingCall内部的停止逻辑。要让任务在异常后继续执行,有两种简单可靠的方案:

方案1:在任务内部捕获异常

最直接的方式是把可能出错的逻辑(比如你的API调用)包裹在try/except块里,让异常不会逃出任务函数,这样LoopingCall会认为任务正常完成,继续调度下一次执行:

import sys
from twisted.internet import reactor, defer, task
from twisted.python import log

def periodic_task():
    log.msg("periodic task running")
    try:
        # 替换成你的实际API调用或业务逻辑
        x = 10 / 0
    except Exception as e:
        # 记录错误信息,也可以在这里添加重试、告警等逻辑
        log.err(e, "periodic_task encountered an error")
    # 函数正常返回,LoopingCall会继续下一轮执行

def periodic_task_crashed(reason):
    log.err(reason, "periodic_task broken")

log.startLogging(sys.stdout)
my_task = task.LoopingCall(periodic_task)
d = my_task.start(1)
d.addErrback(periodic_task_crashed)
reactor.run()

方案2:在Errback中返回成功的Deferred

如果你的任务是异步的(返回Deferred),或者希望在全局Errback中统一处理错误,可以修改Errback函数,让它返回一个成功的Deferred。这样LoopingCall会收到“任务已成功完成”的信号,继续执行下一次:

import sys
from twisted.internet import reactor, defer, task
from twisted.python import log

def periodic_task():
    log.msg("periodic task running")
    x = 10 / 0
    # 如果是异步API调用,示例:
    # return some_async_api_call()

def periodic_task_crashed(reason):
    log.err(reason, "periodic_task broken")
    # 返回成功的Deferred,告知LoopingCall继续执行
    return defer.succeed(None)

log.startLogging(sys.stdout)
my_task = task.LoopingCall(periodic_task)
d = my_task.start(1)
d.addErrback(periodic_task_crashed)
reactor.run()

原理说明

LoopingCall的循环逻辑依赖于任务执行的结果:

  • 如果任务同步执行且无异常,或者异步任务返回成功的Deferred,它会按时调度下一次执行;
  • 只有当任务抛出未捕获的异常,或返回的Deferred进入失败状态且没有被处理为成功时,LoopingCall才会终止循环。

所以上面两种方案都是通过确保任务的最终结果是“成功”的,来让循环持续运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:48:09