Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions django/tasks/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def log_task_started(sender, task_result, **kwargs):

@receiver(task_finished)
def log_task_finished(sender, task_result, **kwargs):
# Signal is sent inside exception handlers, so exc_info() is available.
exc_info = sys.exc_info()
logger.log(
(
logging.ERROR
Expand All @@ -59,6 +61,5 @@ def log_task_finished(sender, task_result, **kwargs):
task_result.id,
task_result.task.module_path,
task_result.status,
# Signal is sent inside exception handlers, so exc_info() is available.
exc_info=sys.exc_info(),
exc_info=exc_info if exc_info[0] else None,
)
22 changes: 13 additions & 9 deletions docs/ref/views.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,20 @@ The 400 (bad request) view

.. function:: defaults.bad_request(request, exception, template_name='400.html')

When a :exc:`~django.core.exceptions.SuspiciousOperation` is raised in Django,
Similarly, Django has a view to handle 400 Bad Request errors.

This view either produces a "Bad Request" message or loads and renders the
template ``400.html`` if you created it in your root template directory.
It returns with status code 400 indicating that the error condition was the
result of a client operation. By default, nothing related to the exception that
triggered the view is passed to the template context, as the exception message
might contain sensitive information like filesystem paths.

``django.views.defaults.bad_request`` is triggered by a
:exc:`~django.core.exceptions.BadRequest` exception. Also, when a
:exc:`~django.core.exceptions.SuspiciousOperation` is raised in Django,
it may be handled by a component of Django (for example resetting the session
data). If not specifically handled, Django will consider the current request a
'bad request' instead of a server error.

``django.views.defaults.bad_request``, is otherwise very similar to the
``server_error`` view, but returns with the status code 400 indicating that
the error condition was the result of a client operation. By default, nothing
related to the exception that triggered the view is passed to the template
context, as the exception message might contain sensitive information like
filesystem paths.
'bad request' instead of a server error, and handle it with ``bad_request``.

``bad_request`` views are also only used when :setting:`DEBUG` is ``False``.
3 changes: 3 additions & 0 deletions docs/releases/6.0.3.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ Bugfixes

* Fixed a visual regression where fieldset legends were misaligned in the admin
(:ticket:`36920`).

* Prevented the :data:`django.tasks.signals.task_finished` signal from writing
extraneous log messages when no exceptions are encountered (:ticket:`36951`).
2 changes: 1 addition & 1 deletion tests/cache/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1992,7 +1992,7 @@ def test_client_driver_info(self):
if {"lib-name", "lib-ver"}.issubset(client_info):
version = django.get_version()
if hasattr(self.lib, "DriverInfo"):
info = self._lib.DriverInfo().add_upstream_driver("django", version)
info = self.lib.DriverInfo().add_upstream_driver("django", version)
correct_lib_name = info.formatted_name
else:
correct_lib_name = f"redis-py(django_v{version})"
Expand Down
4 changes: 3 additions & 1 deletion tests/migrations/test_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,9 @@ def test_loading_order_does_not_create_circular_dependency(self):
test_settings.write(f"INSTALLED_APPS += {INSTALLED_APPS}\n")

test_environ = os.environ.copy()
test_environ["PYTHONPATH"] = str(tests_dir)
test_python_path = sys.path.copy()
test_python_path.append(str(tests_dir))
test_environ["PYTHONPATH"] = os.pathsep.join(test_python_path)
# Ensure deterministic failures.
test_environ["PYTHONHASHSEED"] = "1"

Expand Down
9 changes: 9 additions & 0 deletions tests/tasks/test_immediate_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,15 @@ def test_failed_logs(self):
self.assertIn("state=FAILED", captured_logs.output[2])
self.assertIn(result.id, captured_logs.output[2])

def test_successful_task_no_none_in_logs(self):
with self.assertLogs("django.tasks", level="DEBUG") as captured_logs:
result = test_tasks.noop_task.enqueue()

self.assertEqual(result.status, TaskResultStatus.SUCCESSFUL)

for log_output in captured_logs.output:
self.assertNotIn("None", log_output)

def test_takes_context(self):
result = test_tasks.get_task_id.enqueue()

Expand Down