Fixed #23353 -- Used "raise from" when raising TransactionManagementError.

This change sets the __cause__ attribute to raised exceptions.
This commit is contained in:
David Wobrock 2022-10-02 18:53:05 +02:00 committed by Mariusz Felisiak
parent da02cbd1ef
commit 3b4a5b9f97
4 changed files with 10 additions and 4 deletions

View File

@ -93,6 +93,7 @@ class BaseDatabaseWrapper:
# Tracks if the transaction should be rolled back to the next # Tracks if the transaction should be rolled back to the next
# available savepoint because of an exception in an inner block. # available savepoint because of an exception in an inner block.
self.needs_rollback = False self.needs_rollback = False
self.rollback_exc = None
# Connection termination related attributes. # Connection termination related attributes.
self.close_at = None self.close_at = None
@ -526,7 +527,7 @@ class BaseDatabaseWrapper:
raise TransactionManagementError( raise TransactionManagementError(
"An error occurred in the current transaction. You can't " "An error occurred in the current transaction. You can't "
"execute queries until the end of the 'atomic' block." "execute queries until the end of the 'atomic' block."
) ) from self.rollback_exc
# ##### Foreign key constraints checks handling ##### # ##### Foreign key constraints checks handling #####

View File

@ -118,10 +118,11 @@ def mark_for_rollback_on_error(using=None):
""" """
try: try:
yield yield
except Exception: except Exception as exc:
connection = get_connection(using) connection = get_connection(using)
if connection.in_atomic_block: if connection.in_atomic_block:
connection.needs_rollback = True connection.needs_rollback = True
connection.rollback_exc = exc
raise raise

View File

@ -805,8 +805,9 @@ class SelectOnSaveTests(TestCase):
"An error occurred in the current transaction. You can't " "An error occurred in the current transaction. You can't "
"execute queries until the end of the 'atomic' block." "execute queries until the end of the 'atomic' block."
) )
with self.assertRaisesMessage(DatabaseError, msg): with self.assertRaisesMessage(DatabaseError, msg) as cm:
asos.save(update_fields=["pub_date"]) asos.save(update_fields=["pub_date"])
self.assertIsInstance(cm.exception.__cause__, DatabaseError)
finally: finally:
Article._base_manager._queryset_class = orig_class Article._base_manager._queryset_class = orig_class

View File

@ -339,8 +339,11 @@ class AtomicErrorsTests(TransactionTestCase):
"An error occurred in the current transaction. You can't " "An error occurred in the current transaction. You can't "
"execute queries until the end of the 'atomic' block." "execute queries until the end of the 'atomic' block."
) )
with self.assertRaisesMessage(transaction.TransactionManagementError, msg): with self.assertRaisesMessage(
transaction.TransactionManagementError, msg
) as cm:
r2.save(force_update=True) r2.save(force_update=True)
self.assertIsInstance(cm.exception.__cause__, IntegrityError)
self.assertEqual(Reporter.objects.get(pk=r1.pk).last_name, "Haddock") self.assertEqual(Reporter.objects.get(pk=r1.pk).last_name, "Haddock")
@skipIfDBFeature("atomic_transactions") @skipIfDBFeature("atomic_transactions")