[Zope-dev] ZPatterns: Errors in triggered methods + patch
Steve Alexander
steve@cat-box.net
Wed, 12 Jul 2000 17:03:26 +0100
Latest ZPatterns release. Zope 2.2b4.
If I raise an error in an external method that is called by a
GenericTrigger, I sometimes get a strange log message:
2000-07-12T15:20:07 ERROR(200) ZODB Couldn't load state for
'\000\000\000\000\000\000\021='
Traceback (innermost last):
File .../lib/python/ZODB/Connection.py, line 441, in setstate
File .../lib/python/ZODB/FileStorage.py, line 584, in load
(Object: .../var/Data.fs)
File .../lib/python/ZODB/FileStorage.py, line 560, in _load
(Object: .../var/Data.fs)
KeyError: p=
(Repeated four further times.)
(I replaced the path to my zope installation with "...".)
Sometimes, the characters after the "KeyError:" will be control
characters, and will cause further log output to look like gibberish,
until I suspend the Zope process and type "reset" at the xterm console.
I'm not sure why this happens. I've had another similar log message from
the same sort of cause:
2000-07-12T14:44:01 PANIC(300) ZODB A storage error occurred in the last
phase of a two-phase commit. This shouldn't happen. The application may
be in a hosed state, so we will not allow transactions to commit from
here on
Traceback (innermost last):
File .../lib/python/ZODB/Transaction.py, line 296, in commit
File .../lib/python/Products/ZPatterns/Transactions.py, line 108, in
tpc_finish
File .../lib/python/Products/ZPatterns/Transactions.py, line 135, in
end_tran
File .../lib/python/Products/ZPatterns/DataManagers.py, line 118, in
_cleanup
(Object: Transactional)
File .../lib/python/ZODB/Connection.py, line 441, in setstate
File .../lib/python/ZODB/FileStorage.py, line 584, in load
(Object: .../var/Data.fs)
File .../lib/python/ZODB/FileStorage.py, line 560, in _load
(Object: .../var/Data.fs)
KeyError: p
I guess the methods that GenericTriggers call aren't supposed to throw
exceptions.
However, as a safeguard, how about changing the _checkpoint() method of
Agents.Agent to this:
def _checkpoint(self):
# Send 'final' versions of events
try:
for s,c,m in self._v_tranlog.values():
try:
if s is ChangedStatus:
self._objectChanged(c,m)
elif s is AddedStatus:
self._objectAdded(c)
else:
self._objectDeleted(c,m)
except:
import sys, traceback, string
type, val, tb = sys.exc_info()
sys.stderr.write(string.join( \
traceback.format_exception(type, val, tb),''))
del type, val,
tb
finally:
self._v_tranlog.clear()
I've put the call to each Agent's "change observed" event in a
try-except block. This makes my Zope instance happier when I do stupid
things in external methods, and has the additional advantage of
insulating other Agents from one particular Agent's problems.
--
Steve Alexander
Software Engineer
Cat-Box limited
http://www.cat-box.net