You’re probably here because you’ve stumbled upon a problem with Celery chords. The Chord callback function isn’t executed if one of the tasks in the Chord’s body fails.
This sucks because in most cases, The callback’s execution confirms that all the tasks have been executed by the workers.
We can quickly reproduce this problem in a small python file (I’m using the Redis backend with docker, but you can use any backend that supports chords)
Start a new Redis container with:
Create a new file called test_celery.py
Let’s run the worker file with:
Now, execute the chord:
If you look at the logs you’ll see the exception raised in the bad_task Task but the callback function (i.e tasks_completed) isn’t executed.
The Recommendation from the Celery team is to make your tasks are bullet proof. But this is almost impossible especially when your tasks are communicate with external API’s or depend on external resources.
In celery <= 3.1 There used to be a setting called CELERY_CHORD_PROPAGATES to control this behaviour but it was removed and this is all I could find concerning the removal:
CELERY_CHORD_PROPAGATESsetting will eventually be removed, as it was just added to be backward compatible with the old undefined behavior, which was just accidental and never considered to be a feature.
Anyway, to achieve this we have to monkey patch the redis backend to return a custom value instead of raising a ChordError.
The trackeback already gives us a clue on where to look (Line 352)
patch_celery is a factory function that returns a patched version of Celery’s Redis backend. Instead of raising an exception, we return the Exception class name alongside the exception body.
and you should see something like this in the logs:
We can see that the exception is still raised but now, tasks_completed is executed and we also see the Exception returned as one of the results!
You can also do some interesting things with the task id. Like retrieving the function name, retrying the failed task etc. Hopefully, CELERY_CHORD_PROPAGATES makes it’s way back to Celery.