web-dev-qa-db-ja.com

基になるタスクが例外をスローしても、Celeryが例外をスローしないのはなぜですか

セロリは例外を適切に処理していないようです。

タスクがある場合:

def errorTest():
    raise Exception()

そして私は電話します

r = errorTest.delay()
In [8]: r.result

In [9]: r.state
Out[9]: 'PENDING'

そして、このように無期限にハングアップします。

ログに移動して確認すると、タスクでエラーISがスローされます(そして、メッセージが必要な場合は尋ねます)と表示されます。他のタスクが原因で、バックエンドとすべてが適切に設定されていることがわかります。ちょうど働き、結果を正しく返します。

セロリで例外をキャッチするために必要なファンキーなものはありますか?

/ Celeryのバージョンは3.0.13、ブローカーはローカルマシンで実行されているRabbitMQです。

32
Kevin Meyer

on_failureTaskサブクラスの関数で正しく処理します。何が起こったのかを調べるだけの場合は、セットアップできます error email notifications これにより、セロリの構成でスタックトレースが送信されます。

注:v4 Celeryの時点では メールの送信をサポートするようになりました

13
primalpython

CELERY_ALWAYS_EAGERをTrueに設定してCeleryを実行している場合は、次の行も設定に含めてください。

CELERY_EAGER_PROPAGATES_EXCEPTIONS = True

http://docs.celeryproject.org/en/latest/configuration.html#celery-eager-propagates-exceptions

31
seddonym

@primalpythonの回答をより明確にする予定です。

これは失敗します:

@task
def error():
    raise Exception

入出力:

In [7]: r = error.delay()

In [8]: print r.state
Out[8]: 'PENDING'

In [9]: print r.result
Out[9]: None

これは成功します:

@task
def error():
    raise Exception

    def on_failure(self, *args, **kwargs):
        pass

入出力:

In [7]: r = error.delay()

In [8]: print r.state
Out[8]: 'FAILURE'

In [9]: print r.result
Out[9]: Exception()
3
Kevin Meyer

IMOを使用する最も簡単な方法は、新しいCeleryアプリケーションを作成するときに使用するタスククラスへの参照を渡すことです。

1つのモジュールで、デフォルトで使用するタスククラスを定義します。

from celery.app.task import Task
import logging

logger=logging.getLogger(__name__)

class LoggingTask(Task):
  def on_failure(self, exc, task_id, args, kwargs, einfo):
      kwargs={}
      if logger.isEnabledFor(logging.DEBUG):
         kwargs['exc_info']=exc
      logger.error('Task % failed to execute', task_id, **kwargs)
      super().on_failure(exc, task_id, args, kwargs, einfo)

アプリを定義するときに、モジュールを参照します(注、これは指定した文字列参照です)。

from celery import Celery

app=Celery('my_project_name', task_cls='task_package.module_name:LoggingTask')

それ以降、特にタスククラスが指定されていない場合、LoggingTaskが使用されます。これにより、それぞれを変更する必要がなく、all既存のタスク(デフォルトを使用)を実行できます。これは、@ shared_taskデコレータを通常どおり使用できることも意味します。

1
chander