如何让celery任务从任务中失败?

时间:2011-10-06 09:16:47

标签: celery celery-task

在某些情况下,我想让celery任务从该任务中失败。我尝试了以下方法:

from celery.task import task
from celery import states

@task()
def run_simulation():
    if some_condition:
        run_simulation.update_state(state=states.FAILURE)
        return False

但是,该任务仍然报告已成功:

  

任务sim.tasks.run_simulation [9235e3a7-c6d2-4219-bbc7-acf65c816e65]   成功的1.17847704887s:False

似乎状态只能在任务运行时修改,一旦完成 - 芹菜将状态更改为它认为的结果(参考this question)。有没有办法,通过提出异常来使任务失败,让芹菜返回任务失败?

3 个答案:

答案 0 :(得分:22)

更好的方法是将任务状态更新为FAILURE,然后引发Ignore异常,因为返回任何值都会将任务记录为成功,例如:

from celery import Celery, states
from celery.exceptions import Ignore

app = Celery('tasks', broker='amqp://guest@localhost//')

@app.task(bind=True)
def run_simulation(self):
    if some_condition:
        # manually update the task state
        self.update_state(
            state = states.FAILURE,
            meta = 'REASON FOR FAILURE'
        )

        # ignore the task so no other state is recorded
        raise Ignore()

答案 1 :(得分:2)

我在Ask Solem的问题上得到了一个interesting reply,他提出了一个'after_return'处理程序来解决这个问题。这对未来可能是一个有趣的选择。

与此同时,当我想让它失败然后按如下方式检查时,我只是从任务中返回一个字符串'FAILURE'来解决这个问题:

result = AsyncResult(task_id)
if result.state == 'FAILURE' or (result.state == 'SUCCESS' and result.get() == 'FAILURE'):
    # Failure processing task 

答案 2 :(得分:1)

由于我在使用建议的解决方案时遇到了一些问题,因此我想进一步扩展Pierre的答案。

要在将任务状态更新为states.FAILURE时允许自定义字段,同样重要的是,还要模拟FAILURE状态将具有的某些属性(注意exc_type和exc_message) 解决方案将终止任务时,任何查询状态的尝试(例如-获取“ REASON FOR FAILURE”值)都会失败。

以下是我摘录的摘录: https://www.distributedpython.com/2018/09/28/celery-task-states/

@app.task(bind=True)
def task(self):
    try:
        raise ValueError('Some error')
    except Exception as ex:
        self.update_state(
            state=states.FAILURE,
            meta={
                'exc_type': type(ex).__name__,
                'exc_message': traceback.format_exc().split('\n')
                'custom': '...'
            })
        raise Ignore()