From 97fee0a3c044100ba64aed25651f9f646ed3289f Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Fri, 13 Dec 2024 16:10:20 +0000 Subject: [PATCH] Ensure return value can't be obtained for failed task --- django/tasks/task.py | 8 +++++--- docs/topics/tasks.txt | 3 ++- tests/tasks/test_immediate_backend.py | 4 ++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/django/tasks/task.py b/django/tasks/task.py index f13837472e..fc3b1449b2 100644 --- a/django/tasks/task.py +++ b/django/tasks/task.py @@ -224,11 +224,13 @@ class TaskResult: If the task didn't succeed, an exception is raised. This is to distinguish against the task returning None. """ - if not self.is_finished: + if self.status == ResultStatus.SUCCEEDED: + return self._return_value + elif self.status == ResultStatus.FAILED: + raise ValueError("Task failed") + else: raise ValueError("Task has not finished yet") - return self._return_value - @property def exception_class(self): """The exception raised by the task function""" diff --git a/docs/topics/tasks.txt b/docs/topics/tasks.txt index e3b15c1dea..58854516c9 100644 --- a/docs/topics/tasks.txt +++ b/docs/topics/tasks.txt @@ -315,7 +315,8 @@ Return values If your task function returns something, it can be retrieved from the :attr:`django.tasks.TaskResult.return_value` attribute:: - result.return_value # 42 + if result.status == ResultStatus.SUCCEEDED: + result.return_value # 42 If the task has not finished executing, or has failed, :exc:`ValueError` is raised. diff --git a/tests/tasks/test_immediate_backend.py b/tests/tasks/test_immediate_backend.py index 0b424ca89d..ab20e4f4a3 100644 --- a/tests/tasks/test_immediate_backend.py +++ b/tests/tasks/test_immediate_backend.py @@ -82,6 +82,8 @@ class ImmediateBackendTestCase(SimpleTestCase): # assert result self.assertEqual(result.status, ResultStatus.FAILED) + with self.assertRaisesMessage(ValueError, "Task failed"): + result.return_value self.assertTrue(result.is_finished) self.assertIsNotNone(result.started_at) self.assertIsNotNone(result.finished_at) @@ -111,6 +113,8 @@ class ImmediateBackendTestCase(SimpleTestCase): result = test_tasks.complex_exception.enqueue() self.assertEqual(result.status, ResultStatus.FAILED) + with self.assertRaisesMessage(ValueError, "Task failed"): + result.return_value self.assertIsNotNone(result.started_at) self.assertIsNotNone(result.finished_at) self.assertGreaterEqual(result.started_at, result.enqueued_at)