首页 > 解决方案 > Celery - 异常重新引发信息

问题描述

使用芹菜,如果我定义以下任务:

@app.task(bind=True)
def Cmd(self):
    self.log.info(f"Running cmd")
    with open(f'/tmp/nopermission', 'w') as file:
         ...

我开始我的芹菜工人,然后从我的 main.py 开始:

res = Cmd.delay()
print(res.get())

在工人的日志中,我得到:

Traceback (most recent call last):
  ...
  File "tasks.py", line 5, in Cmd
    with open(f'/tmp/nopermission', 'w') as file:
PermissionError: [Errno 13] Permission denied: '/tmp/nopermission'

但是,这print(res.get())给了我:

 File "site-packages/celery/result.py", line 211, in get
    self._maybe_reraise_parent_error()
  File "site-packages/celery/result.py", line 234, in _maybe_reraise_parent_error
    node.maybe_throw()
  File "site-packages/celery/result.py", line 333, in maybe_throw
    self.throw(value, self._to_remote_traceback(tb))
  File "site-packages/celery/result.py", line 326, in throw
    self.on_ready.throw(*args, **kwargs)
  File "vine/promises.py", line 244, in throw
    reraise(type(exc), exc, tb)
  File "vine/five.py", line 195, in reraise
    raise value
PermissionError: [Errno 13] Permission denied

基本上,我没有关于确切错误的信息(在这种情况下,是文件名)。这是为什么?

而且,作为一个更普遍的问题,将额外数据附加到我的结果的最优雅的方式是什么?例如,我在 app.conf.workername 中有执行任务的工作人员的名称。我会使用任务基类中的 on_failure / on_success 处理程序吗?(app = Celery(task_cls='path:baseTask'))

标签: pythonexceptionceleryraise

解决方案


我找到了一种方法,但这样做,我想我发现了一个错误。

在启动 celery ( Celery(task_cls='path:baseTask'))时的 baseTask 类中

class baseTask(Task):    
    def on_failure(self, exc, task_id, args, kwargs, einfo):
        self.log.error(f'{self.name} on {self.worker} failed after {self.execTime} seconds: {exc}')
        self.update_state(state=states.FAILURE, meta={
                'exc_type': type(exc).__name__,
                'exc_message': traceback.format_exc().split('\n'),
                'extra': "something"})

然后,运行任何任务:

try:
    task.delay()
    print(task.get())
except Exception as exc:
    time.sleep(2)
    info = task.backend.get(res.backend.get_key_for_task(task.id)).decode(encoding='UTF-8')
    info = json.loads(info)
    print(info['result']['extra'])
    raise exc

为什么要睡觉?好吧,如果我不这样做,并且继续运行我的 Cmd 任务,一半的时间,我不会在“结果”中得到“额外”。这是相当随机的,但睡眠似乎可以解决问题。不过,我很想知道为什么 :) 我有 celery 4.4.2,transport:amqp,results:redis。


推荐阅读