#20030: django.db.backends.BaseDatabaseWrapper.supports_transactions eats 
database
exceptions
----------------------------------------------+--------------------
     Reporter:  gcc                           |      Owner:  nobody
         Type:  Bug                           |     Status:  new
    Component:  Database layer (models, ORM)  |    Version:  1.5
     Severity:  Normal                        |   Keywords:
 Triage Stage:  Unreviewed                    |  Has patch:  1
Easy pickings:  0                             |      UI/UX:  0
----------------------------------------------+--------------------
 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()
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/20030>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to