Skip to content

Commit 92d191a

Browse files
authored
Merge pull request #57 from taskbadger/sk/ctask-none
Guard against unregistered task in before_task_publish handler
2 parents eb1d75d + c2e409b commit 92d191a

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

taskbadger/celery.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ def task_publish_handler(sender=None, headers=None, body=None, **kwargs):
170170
if task:
171171
meta = {TB_TASK_ID: task.id}
172172
headers.update(meta)
173-
ctask.update_state(task_id=headers["id"], state="PENDING", meta=meta)
173+
if ctask:
174+
ctask.update_state(task_id=headers["id"], state="PENDING", meta=meta)
174175

175176

176177
def _maybe_create_task(signal_sender):

tests/test_celery.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from kombu.utils.json import register_type
1818

1919
from taskbadger import Action, EmailIntegration, StatusEnum
20-
from taskbadger.celery import Task
20+
from taskbadger.celery import Task, task_publish_handler
2121
from taskbadger.mug import Badger
2222
from tests.utils import task_for_test
2323

@@ -280,6 +280,23 @@ def add_with_task_args_in_decorator(self, a, b):
280280
)
281281

282282

283+
@pytest.mark.usefixtures("_bind_settings")
284+
def test_celery_publish_handler_task_not_registered_locally():
285+
"""before_task_publish can fire in a process that never imported the task
286+
being sent (e.g. a producer-only service), so `celery.current_app.tasks.get`
287+
returns None. The handler should still create the TaskBadger task without
288+
blowing up trying to call `.update_state()` on the missing task class."""
289+
290+
with mock.patch("taskbadger.celery.create_task_safe") as create:
291+
create.return_value = task_for_test()
292+
293+
headers = {"id": "abc123", "task": "unregistered.task", "taskbadger_track": True}
294+
task_publish_handler(sender="unregistered.task", headers=headers, body=[[], {}, {}])
295+
296+
create.assert_called_once()
297+
assert headers["taskbadger_task_id"] == create.return_value.id
298+
299+
283300
@pytest.mark.usefixtures("_bind_settings")
284301
def test_celery_task_custom_queue(celery_session_app, celery_session_worker):
285302
@celery_session_app.task(bind=True, base=Task)

0 commit comments

Comments
 (0)