This commit is contained in:
Krishnaprasad MG 2025-11-17 18:45:02 +01:00 committed by GitHub
commit a605aa9583
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 66 additions and 10 deletions

View file

@ -741,10 +741,10 @@ class BaseDatabaseWrapper:
try: try:
func() func()
except Exception as e: except Exception as e:
logger.error( name = getattr(func, "__qualname__", func)
f"Error calling {func.__qualname__} in on_commit() (%s).", logger.exception(
f"Error calling {name} in on_commit() (%s).",
e, e,
exc_info=True,
) )
else: else:
func() func()
@ -759,11 +759,11 @@ class BaseDatabaseWrapper:
try: try:
func() func()
except Exception as e: except Exception as e:
logger.error( name = getattr(func, "__qualname__", func)
f"Error calling {func.__qualname__} in on_commit() during " logger.exception(
f"Error calling {name} in on_commit() during "
f"transaction (%s).", f"transaction (%s).",
e, e,
exc_info=True,
) )
else: else:
func() func()

View file

@ -1523,11 +1523,10 @@ class TestCase(TransactionTestCase):
try: try:
callback() callback()
except Exception as e: except Exception as e:
logger.error( name = getattr(callback, "__qualname__", callback)
f"Error calling {callback.__qualname__} in " logger.exception(
f"on_commit() (%s).", f"Error calling {name} in on_commit() (%s).",
e, e,
exc_info=True,
) )
else: else:
callback() callback()

View file

@ -4,6 +4,7 @@ import threading
import traceback import traceback
import unittest import unittest
import warnings import warnings
from functools import partial
from io import StringIO from io import StringIO
from unittest import mock from unittest import mock
@ -2145,6 +2146,35 @@ class CaptureOnCommitCallbacksTests(TestCase):
self.assertIsInstance(raised_exception, MyException) self.assertIsInstance(raised_exception, MyException)
self.assertEqual(str(raised_exception), "robust callback") 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.assertRegex(
log_record.getMessage(),
r"Error calling functools\.partial\(<function CaptureOnCommitCallbacksTests"
r"\.test_execute_robust_with_callback_as_partial\.<locals>\.hook"
r" at .+>\) 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): class DisallowedDatabaseQueriesTests(SimpleTestCase):
def test_disallowed_database_connections(self): def test_disallowed_database_connections(self):

View file

@ -1,3 +1,5 @@
from functools import partial
from django.db import connection, transaction from django.db import connection, transaction
from django.test import TransactionTestCase, skipUnlessDBFeature from django.test import TransactionTestCase, skipUnlessDBFeature
@ -84,6 +86,31 @@ class TestConnectionOnCommit(TransactionTestCase):
self.assertIsInstance(raised_exception, ForcedError) self.assertIsInstance(raised_exception, ForcedError)
self.assertEqual(str(raised_exception), "robust callback") 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.assertRegex(
log_record.getMessage(),
r"Error calling functools\.partial\(<function TestConnectionOnCommit\."
r"test_robust_transaction_with_callback_as_partial\.<locals>\."
r"robust_callback at .+>\) in on_commit\(\)"
r" 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): def test_delays_execution_until_after_transaction_commit(self):
with transaction.atomic(): with transaction.atomic():
self.do(1) self.do(1)