Opened 11 years ago

Closed 11 years ago

#20030 closed Bug (wontfix)

django.db.backends.BaseDatabaseWrapper.supports_transactions eats database exceptions

Reported by: Chris Wilson Owned by: nobody
Component: Database layer (models, ORM) Version: 1.5
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When there's a problem with the database configuration, running tests can generate this error:

======================================================================
ERROR: test_admin_interface_can_view_curriculum (lessons.tests.LessonsAppTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 259, in __call__
    self._pre_setup()
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/intranet_binder/test_utils.py", line 205, in _pre_setup
    super(AptivateEnhancedTestCase, self)._pre_setup()
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 479, in _pre_setup
    self._fixture_setup()
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 829, in _fixture_setup
    if not connections_support_transactions():
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 816, in connections_support_transactions
    for conn in connections.all())
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 816, in <genexpr>
    for conn in connections.all())
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/utils/functional.py", line 43, in __get__
    res = instance.__dict__[self.func.__name__] = self.func(instance)
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/db/backends/__init__.py", line 455, in supports_transactions
    self.connection.leave_transaction_management()
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/db/backends/__init__.py", line 138, in leave_transaction_management
    "Transaction managed block ended with pending COMMIT/ROLLBACK")
TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK

Which totally hides the nature of the error, which was:

Traceback (most recent call last):
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 259, in __call__
    self._pre_setup()
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/intranet_binder/test_utils.py", line 205, in _pre_setup
    super(AptivateEnhancedTestCase, self)._pre_setup()
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 479, in _pre_setup
    self._fixture_setup()
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 829, in _fixture_setup
    if not connections_support_transactions():
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 816, in connections_support_transactions
    for conn in connections.all())
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/test/testcases.py", line 816, in <genexpr>
    for conn in connections.all())
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/utils/functional.py", line 43, in __get__
    res = instance.__dict__[self.func.__name__] = self.func(instance)
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/db/backends/__init__.py", line 445, in supports_transactions
    cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 366, in execute
    six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
  File "/home/installuser/Dropbox/projects/ischool/user_manager/django/project/.ve/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 362, in execute
    return Database.Cursor.execute(self, query, params)
DatabaseError: attempt to write a readonly database

The exception thrown by the finally clause in supports_transactions obscures the real error by throwing a new one.

I modified supports_transactions so that if the finally block throws an exception, it's silently ignored, and the original error is allowed to propagate upwards, instead of being swallowed by a meaningless one:

         finally:
-            self.connection.leave_transaction_management()
+            try:
+                self.connection.leave_transaction_management()
+            except:
+                pass # let the exception propagate upwards
         return count == 0

Maybe we should only do that if the test code actually threw an exception:

            self.connection._dirty = False
+        except:
+            try:
+                self.connection.leave_transaction_management()
+            except:
+                pass # let the exception propagate upwards
+            
        finally:
            self.connection.leave_transaction_management()

Change History (2)

comment:1 by Aymeric Augustin, 11 years ago

As of yesterday, this code is deprecated.

comment:2 by Jacob, 11 years ago

Resolution: wontfix
Status: newclosed

As aaugustin says, since this code is deprecated we're not going to fix this.

Note: See TracTickets for help on using tickets.
Back to Top