[Zope-dev] Zope 2: ZPublisher exception handling
yuppie
y.2010 at wcm-solutions.de
Mon Apr 12 05:33:37 EDT 2010
Hi!
Summary:
========
In Zope 2.10 'raise_standardErrorMessage', 'zpublisher_exception_hook'
and therefore 'Publish.publish' did always (re-)raise errors after
rendering. That made sure 'HTTPResponse.exception' was called and
CookieCrumbler was able to hook into 'HTTPResponse._unauthorized'.
I'm now trying to figure out how this bug could be fixed:
https://bugs.launchpad.net/zope-cmf/+bug/558340
Some details:
=============
In Zope 2.10 and earlier the code did (re-)raise errors this way:
raise error_type, error_value, traceback
'error_type' is the original error class, 'error_value' the rendered
error message. Python creates a new error instance, basically trying to
do this:
error_instance = error_type(error_value)
That doesn't work if the error class constructor requires more than one
argument.
This was the first change that broke the old behavior:
http://svn.zope.org/?view=rev&rev=77459
The comment in Zope2/App/startup.py is interesting because it says
"raise the rendered value" while the code actually *returns* it:
# Lookup a view for the exception and render it, then
# raise the rendered value as the exception value
# (basically the same that 'raise_standardErrorMessage'
# does.
I guess the checkin message for http://svn.zope.org/?view=rev&rev=92767
explains why:
"Rather nasty fix to work around Zope 3 exceptions that have more than
one positional argument on the constructor."
The old machinery doesn't work with ZTK exceptions like
zope.publisher.interfaces.NotFound because they take additional
arguments and have are more complex __str__ method.
There is an inconsistency in revision 92767 (
http://svn.zope.org/Zope/trunk/lib/python/OFS/SimpleItem.py?rev=92767&view=diff&r1=92767&r2=92766
):
The checkin message says: "work around Zope 3 exceptions that have *more
than one* positional argument". I think that's correct.
The comment in SimpleItem.py says something different:
# Can we re-raise the exception with a rendered-to-HTML
# exception value? To be able to do so, the exception
# constructor needs to be able to take more than two
# arguments (some Zope exceptions can't).
The code follows that comment, so 'can_raise' is sometimes wrong.
E.g. can_raise is True for zope.publisher.interfaces.NotFound, but
re-raising with the rendered value as only argument doesn't work.
Proposal:
=========
We could try to fix bugs like the one mentioned above. And we could
restore the old behavior for normal Zope 2 exceptions, fixing the
CookieCrumbler issue.
But the whole thing looks like a big mess. I think we should try to find
a way to treat all kinds of errors the same way.
I see two possible approaches:
1.) Stop re-raising errors. Always return rendered values and pass them
on to the places where the errors are currently catched.
2.) Re-raise the original errors. And store the rendered value somewhere
else. Maybe in the response object.
What do you think? Any comments are welcome.
Cheers,
Yuppie
More information about the Zope-Dev
mailing list