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
# available savepoint because of an exception in an inner block.
self.needs_rollback = False
self.rollback_exc = None
# Connection termination related attributes.
self.close_at = None
@ -526,7 +527,7 @@ class BaseDatabaseWrapper:
raise TransactionManagementError(
"An error occurred in the current transaction. You can't "
"execute queries until the end of the 'atomic' block."
)
) from self.rollback_exc
# ##### Foreign key constraints checks handling #####

View File

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

View File

@ -805,8 +805,9 @@ class SelectOnSaveTests(TestCase):
"An error occurred in the current transaction. You can't "
"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"])
self.assertIsInstance(cm.exception.__cause__, DatabaseError)
finally:
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 "
"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)
self.assertIsInstance(cm.exception.__cause__, IntegrityError)
self.assertEqual(Reporter.objects.get(pk=r1.pk).last_name, "Haddock")
@skipIfDBFeature("atomic_transactions")