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

View file

@ -1523,11 +1523,10 @@ 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(
f"Error calling {name} in on_commit() (%s).",
e,
exc_info=True,
)
else:
callback()

View file

@ -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,35 @@ 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.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):
def test_disallowed_database_connections(self):

View file

@ -1,3 +1,5 @@
from functools import partial
from django.db import connection, transaction
from django.test import TransactionTestCase, skipUnlessDBFeature
@ -84,6 +86,31 @@ 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.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):
with transaction.atomic():
self.do(1)