[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