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

Celery 4.3.0中Chord的on_error回调参数缺失引发TypeError问题

解决Celery 4.3.0中Chord on_error回调的TypeError问题

我之前在使用Celery 4.x版本时也碰到过这个问题,核心原因是你定义的错误回调函数参数签名和Celery 4.3.0中chord的on_error要求的不匹配。

问题分析

你的on_chord_error函数定义为:

@app.task(name='tasks.on_chord_error')
def on_chord_error(request, exc, traceback):
    print('>>>>>>>>>>>>>>>>>> Task {0!r} raised error: {1!r}'.format(request.id, exc))

但在Celery 4.3.0中,chord的on_error回调默认传递的参数顺序是**exc(异常对象)、traceback(回溯对象)、task_id(失败任务ID)、args(失败任务的位置参数)、kwargs(失败任务的关键字参数)**,并不直接传递request对象。这就导致调用时参数数量和顺序不匹配,触发TypeError。

解决方案

根据你的需求,有两种调整方式:

方式一:调整函数参数匹配Celery的默认传递

直接修改on_chord_error的参数签名,接收Celery传递的参数:

@app.task(name='tasks.on_chord_error')
def on_chord_error(exc, traceback, task_id, args, kwargs):
    print('>>>>>>>>>>>>>>>>>> Task {0!r} raised error: {1!r}'.format(task_id, exc))

这样调用时参数就能完全匹配,不会报错。如果需要获取更多任务上下文,可以通过task_id去查询任务信息。

方式二:绑定任务获取Request对象

如果确实需要request对象(比如要获取更多任务元数据),可以给任务添加bind=True参数,让第一个参数绑定为任务实例(包含request属性):

@app.task(bind=True, name='tasks.on_chord_error')
def on_chord_error(self, exc, traceback, task_id, args, kwargs):
    # 通过self.request获取任务请求信息
    print('>>>>>>>>>>>>>>>>>> Task {0!r} raised error: {1!r}'.format(self.request.id, exc))

这种方式既符合Celery的参数传递规则,又能拿到你需要的request相关数据。

验证修改后的完整代码

调整后的完整代码示例:

from celery import Celery, group, chord

app = Celery('tasks', broker='redis://localhost:6379/0')

@app.task(name='tasks.add')
def add(x, y):
    # 可以故意抛出异常测试错误回调
    # if x == 2:
    #     raise ValueError("Test error")
    return x + y

@app.task(name='tasks.callback')
def callback(result):
    print('>>>>>>>>>>>>>>>>>> callback {0}'.format(result))
    return result

@app.task(name='tasks.on_chord_error')
def on_chord_error(exc, traceback, task_id, args, kwargs):
    print('>>>>>>>>>>>>>>>>>> Task {0!r} raised error: {1!r}'.format(task_id, exc))

# 调用chord的代码保持不变
chord_head_list = (add.s(i, i) for i in range(4))
res_chord = (group(chord_head_list) | callback.s().on_error(on_chord_error.s())).delay()
print(res_chord.get(timeout=20))

这样修改后,chord的错误回调就能正常触发,不会再出现参数缺失的TypeError。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:14:15