[Zope3-dev] Uncaught errors in functional test (DebugSkinTests)

Tim Peters tim.peters at gmail.com
Sat Apr 2 18:17:52 EST 2005


This one gets uncaught errors in isolation:

"""
C:\Code\Zope3>\python23\python.exe test.py -vvf . testNotFound
Configuration file found.
Running FUNCTIONAL tests at level 1
Running FUNCTIONAL tests from C:\Code\Zope3
Parsing ftesting.zcml
testNotFound (zope.app.debugskin.ftests.DebugSkinTests) ...
Exception ZODB.POSException.ConnectionStateError:
<ZODB.POSException.ConnectionStateError instance at 0x03418490> in
<bound method Cleanup.__del__ of
<zope.app.publication.zopepublication.Cleanup object at 0x0340F9B0>>
ignored
Exception ZODB.POSException.ConnectionStateError:
<ZODB.POSException.ConnectionStateError instance at 0x020875A8> in
<bound method Cleanup.__del__ of
<zope.app.publication.zopepublication.Cleanup object at 0x03419110>>
ignored
ok
testNotFound (zope.app.exception.browser.ftests.TestNotFound) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.547s

OK
"""

I don't know whether this is new, but I have a vague memory of bumping
into this some weeks ago.  The switch to using ZODB 3.4a2 definitely
isn't relevant.

ConnectionStateError is raised by ZODB when:

1. An attempt to commit a transaction T (or subtransaction) fails.
2. T isn't explicitly aborted.
3. An attempt is made to close a Connection involved in the failing T.

unittest doesn't notice the failures because the exceptions are raised
in a __del__ method, and Python can't raise exceptions that occur in
__del__ methods (Python just prints info about such exceptions).

This patch makes the exceptions go away, but I don't know whether it's
the right thing to do -- ZODB raises ConnectionStateError precisely
because it's impossible to guess what the user's intent was when they
try to close a connection with a transaction still in a damaged state.
 Best guess is that this patch isn't the right solution, and that the
publication machinery should be explicitly aborting transactions that
fail; for that matter, relying on a __del__ method for *anything* here
just doesn't smell right:

Index: src/zope/app/publication/zopepublication.py
===================================================================
--- src/zope/app/publication/zopepublication.py (revision 29848)
+++ src/zope/app/publication/zopepublication.py (working copy)
@@ -137,7 +137,11 @@
         version = request.get(self.version_cookie, '')
         conn = self.db.open(version)

-        cleanup = Cleanup(conn.close)
+        def close_connection():
+            transaction.abort()
+            conn.close()
+
+        cleanup = Cleanup(close_connection)
         request.hold(cleanup)  # Close the connection on request.close()

         self.openedConnection(conn)


More information about the Zope3-dev mailing list