summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrishnaprasad MG <krishna@holvi.com>2025-12-15 15:39:06 +0100
committerJacob Walls <jacobtylerwalls@gmail.com>2025-12-19 12:58:29 -0500
commit7a2f35b1b755b20a1e4d290a88bf059e6897f798 (patch)
treefba0bbd7a6f6475645b8262f443652da5b5d1c58
parent60fecd1d445224fa00385f5f1fde75999da7bec8 (diff)
Fixed #36487 -- Fixed logger error message with partial callbacks.
-rw-r--r--django/db/backends/base/base.py15
-rw-r--r--django/test/testcases.py8
-rw-r--r--tests/test_utils/tests.py28
-rw-r--r--tests/transaction_hooks/tests.py47
4 files changed, 85 insertions, 13 deletions
diff --git a/django/db/backends/base/base.py b/django/db/backends/base/base.py
index 3f3d29874a..23015a57a3 100644
--- a/django/db/backends/base/base.py
+++ b/django/db/backends/base/base.py
@@ -741,11 +741,8 @@ class BaseDatabaseWrapper:
try:
func()
except Exception as e:
- logger.error(
- f"Error calling {func.__qualname__} in on_commit() (%s).",
- e,
- exc_info=True,
- )
+ name = getattr(func, "__qualname__", func)
+ logger.exception("Error calling %s in on_commit() (%s).", name, e)
else:
func()
@@ -759,11 +756,11 @@ class BaseDatabaseWrapper:
try:
func()
except Exception as e:
- logger.error(
- f"Error calling {func.__qualname__} in on_commit() during "
- f"transaction (%s).",
+ name = getattr(func, "__qualname__", func)
+ logger.exception(
+ "Error calling %s in on_commit() during transaction (%s).",
+ name,
e,
- exc_info=True,
)
else:
func()
diff --git a/django/test/testcases.py b/django/test/testcases.py
index c587f770a6..c56fa52806 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -1523,11 +1523,11 @@ class TestCase(TransactionTestCase):
try:
callback()
except Exception as e:
- logger.error(
- f"Error calling {callback.__qualname__} in "
- f"on_commit() (%s).",
+ name = getattr(callback, "__qualname__", callback)
+ logger.exception(
+ "Error calling %s in on_commit() (%s).",
+ name,
e,
- exc_info=True,
)
else:
callback()
diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py
index 70cca3d441..92f13ab81c 100644
--- a/tests/test_utils/tests.py
+++ b/tests/test_utils/tests.py
@@ -4,6 +4,7 @@ import threading
import traceback
import unittest
import warnings
+from functools import partial
from io import StringIO
from unittest import mock
@@ -2145,6 +2146,33 @@ class CaptureOnCommitCallbacksTests(TestCase):
self.assertIsInstance(raised_exception, MyException)
self.assertEqual(str(raised_exception), "robust callback")
+ def test_execute_robust_with_callback_as_partial(self):
+ class MyException(Exception):
+ pass
+
+ def hook():
+ self.callback_called = True
+ raise MyException("robust callback")
+
+ hook_partial = partial(hook)
+
+ with self.assertLogs("django.test", "ERROR") as cm:
+ with self.captureOnCommitCallbacks(execute=True) as callbacks:
+ transaction.on_commit(hook_partial, robust=True)
+
+ self.assertEqual(len(callbacks), 1)
+ self.assertIs(self.callback_called, True)
+
+ log_record = cm.records[0]
+ self.assertEqual(
+ log_record.getMessage(),
+ f"Error calling {hook_partial} in on_commit() (robust callback).",
+ )
+ self.assertIsNotNone(log_record.exc_info)
+ raised_exception = log_record.exc_info[1]
+ self.assertIsInstance(raised_exception, MyException)
+ self.assertEqual(str(raised_exception), "robust callback")
+
class DisallowedDatabaseQueriesTests(SimpleTestCase):
def test_disallowed_database_connections(self):
diff --git a/tests/transaction_hooks/tests.py b/tests/transaction_hooks/tests.py
index 938e92575f..5390165072 100644
--- a/tests/transaction_hooks/tests.py
+++ b/tests/transaction_hooks/tests.py
@@ -1,3 +1,5 @@
+from functools import partial
+
from django.db import connection, transaction
from django.test import TransactionTestCase, skipUnlessDBFeature
@@ -63,6 +65,28 @@ class TestConnectionOnCommit(TransactionTestCase):
self.assertIsInstance(raised_exception, ForcedError)
self.assertEqual(str(raised_exception), "robust callback")
+ def test_robust_if_no_transaction_with_callback_as_partial(self):
+ def robust_callback():
+ raise ForcedError("robust callback")
+
+ robust_callback_partial = partial(robust_callback)
+
+ with self.assertLogs("django.db.backends.base", "ERROR") as cm:
+ transaction.on_commit(robust_callback_partial, robust=True)
+ self.do(1)
+
+ self.assertDone([1])
+ log_record = cm.records[0]
+ self.assertEqual(
+ log_record.getMessage(),
+ f"Error calling {robust_callback_partial} "
+ f"in on_commit() (robust callback).",
+ )
+ self.assertIsNotNone(log_record.exc_info)
+ raised_exception = log_record.exc_info[1]
+ self.assertIsInstance(raised_exception, ForcedError)
+ self.assertEqual(str(raised_exception), "robust callback")
+
def test_robust_transaction(self):
def robust_callback():
raise ForcedError("robust callback")
@@ -84,6 +108,29 @@ class TestConnectionOnCommit(TransactionTestCase):
self.assertIsInstance(raised_exception, ForcedError)
self.assertEqual(str(raised_exception), "robust callback")
+ def test_robust_transaction_with_callback_as_partial(self):
+ def robust_callback():
+ raise ForcedError("robust callback")
+
+ robust_callback_partial = partial(robust_callback)
+
+ with self.assertLogs("django.db.backends", "ERROR") as cm:
+ with transaction.atomic():
+ transaction.on_commit(robust_callback_partial, robust=True)
+ self.do(1)
+
+ self.assertDone([1])
+ log_record = cm.records[0]
+ self.assertEqual(
+ log_record.getMessage(),
+ f"Error calling {robust_callback_partial} in on_commit() during "
+ "transaction (robust callback).",
+ )
+ self.assertIsNotNone(log_record.exc_info)
+ raised_exception = log_record.exc_info[1]
+ self.assertIsInstance(raised_exception, ForcedError)
+ self.assertEqual(str(raised_exception), "robust callback")
+
def test_delays_execution_until_after_transaction_commit(self):
with transaction.atomic():
self.do(1)