Quellcode durchsuchen

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

This change sets the __cause__ attribute to raised exceptions.
David Wobrock vor 2 Jahren
Ursprung
Commit
3b4a5b9f97
4 geänderte Dateien mit 10 neuen und 4 gelöschten Zeilen
  1. 2 1
      django/db/backends/base/base.py
  2. 2 1
      django/db/transaction.py
  3. 2 1
      tests/basic/tests.py
  4. 4 1
      tests/transactions/tests.py

+ 2 - 1
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 #####
 

+ 2 - 1
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
 
 

+ 2 - 1
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
 

+ 4 - 1
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")