@@ -50,19 +50,57 @@ async def test_enqueue_task_async(self) -> None:
5050 self .assertEqual (result .kwargs , {})
5151
5252 def test_catches_exception (self ) -> None :
53- result = default_task_backend .enqueue (test_tasks .failing_task , [], {})
53+ test_data = [
54+ (
55+ test_tasks .failing_task_value_error , # task function
56+ ValueError , # expected exception
57+ "This task failed due to ValueError" , # expected message
58+ ),
59+ (
60+ test_tasks .failing_task_system_exit ,
61+ SystemExit ,
62+ "This task failed due to SystemExit" ,
63+ ),
64+ ]
65+ for task , exception , message in test_data :
66+ with self .subTest (task ), self .assertLogs (
67+ "django_tasks.backends.immediate" , level = "ERROR"
68+ ) as captured_logs :
69+ result = default_task_backend .enqueue (task , [], {})
70+
71+ # assert logging
72+ self .assertEqual (len (captured_logs .output ), 1 )
73+ self .assertIn (message , captured_logs .output [0 ])
74+
75+ # assert result
76+ self .assertEqual (result .status , ResultStatus .FAILED )
77+ self .assertIsNotNone (result .started_at )
78+ self .assertIsNotNone (result .finished_at )
79+ self .assertGreaterEqual (result .started_at , result .enqueued_at )
80+ self .assertGreaterEqual (result .finished_at , result .started_at )
81+ self .assertIsInstance (result .result , exception )
82+ self .assertTrue (
83+ result .traceback .endswith (f"{ exception .__name__ } : { message } \n " )
84+ )
85+ self .assertIsNone (result .get_result ())
86+ self .assertEqual (result .task , task )
87+ self .assertEqual (result .args , [])
88+ self .assertEqual (result .kwargs , {})
5489
55- self .assertEqual (result .status , ResultStatus .FAILED )
56- self .assertIsNotNone (result .started_at )
57- self .assertIsNotNone (result .finished_at )
58- self .assertGreaterEqual (result .started_at , result .enqueued_at )
59- self .assertGreaterEqual (result .finished_at , result .started_at )
60- self .assertIsInstance (result .result , ValueError )
61- self .assertTrue (result .traceback .endswith ("ValueError: This task failed\n " ))
62- self .assertIsNone (result .get_result ())
63- self .assertEqual (result .task , test_tasks .failing_task )
64- self .assertEqual (result .args , [])
65- self .assertEqual (result .kwargs , {})
90+ def test_throws_keyboard_interrupt (self ) -> None :
91+ with self .assertRaises (KeyboardInterrupt ):
92+ with self .assertLogs (
93+ "django_tasks.backends.immediate" , level = "ERROR"
94+ ) as captured_logs :
95+ default_task_backend .enqueue (
96+ test_tasks .failing_task_keyboard_interrupt , [], {}
97+ )
98+
99+ # assert logging
100+ self .assertEqual (len (captured_logs .output ), 1 )
101+ self .assertIn (
102+ "This task failed due to KeyboardInterrupt" , captured_logs .output [0 ]
103+ )
66104
67105 def test_complex_exception (self ) -> None :
68106 with self .assertLogs ("django_tasks.backends.immediate" , level = "ERROR" ):
@@ -134,7 +172,7 @@ def test_cannot_pass_run_after(self) -> None:
134172 "Backend does not support run_after" ,
135173 ):
136174 default_task_backend .validate_task (
137- test_tasks .failing_task .using (run_after = timezone .now ())
175+ test_tasks .failing_task_value_error .using (run_after = timezone .now ())
138176 )
139177
140178 def test_meaning_of_life_view (self ) -> None :
0 commit comments