summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wobrock <david.wobrock@gmail.com>2022-10-02 18:53:05 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-10-03 06:08:54 +0200
commit3b4a5b9f97f113ca5151cff744019e39a1ed7475 (patch)
tree6772017c8d6ba1ed54871172852ab31e5210cab9
parentda02cbd1effc951b14c981925d0e26a39566649e (diff)
Fixed #23353 -- Used "raise from" when raising TransactionManagementError.
This change sets the __cause__ attribute to raised exceptions.
-rw-r--r--django/db/backends/base/base.py3
-rw-r--r--django/db/transaction.py3
-rw-r--r--tests/basic/tests.py3
-rw-r--r--tests/transactions/tests.py5
4 files changed, 10 insertions, 4 deletions
diff --git a/django/db/backends/base/base.py b/django/db/backends/base/base.py
index 3f07b4231a..f04bd8882a 100644
--- a/django/db/backends/base/base.py
+++ b/django/db/backends/base/base.py
@@ -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 #####
diff --git a/django/db/transaction.py b/django/db/transaction.py
index e57e1d0a6f..4150cbcbbe 100644
--- a/django/db/transaction.py
+++ b/django/db/transaction.py
@@ -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
diff --git a/tests/basic/tests.py b/tests/basic/tests.py
index 44ace3d684..1d91e39ce9 100644
--- a/tests/basic/tests.py
+++ b/tests/basic/tests.py
@@ -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
diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py
index a528ab22e5..bdf912653c 100644
--- a/tests/transactions/tests.py
+++ b/tests/transactions/tests.py
@@ -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")