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
相关产品推荐
相关产品推荐

