From d96ff9144f98bb44254f77f56e55967c46b09774 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Aug 2010 07:25:28 +0000 Subject: - New public interface: ``repoze.bfg.exceptions.IExceptionResponse``. This interface is provided by all internal exception classes (such as ``repoze.bfg.exceptions.NotFound`` and ``repoze.bfg.exceptions.Forbidden``), instances of which are both exception objects and can behave as WSGI response objects. This interface is made public so that exception classes which are also valid WSGI response factories can be configured to implement them or exception instances which are also or response instances can be configured to provide them. - New API class: ``repoze.bfg.view.AppendSlashNotFoundViewFactory`` (undoes previous custom_notfound_view on request passsed to append_slash_notfound_view). - Previously, two default view functions were registered at Configurator setup (one for ``repoze.bfg.exceptions.NotFound`` named ``default_notfound_view`` and one for ``repoze.bfg.exceptions.Forbidden`` named ``default_forbidden_view``) to render internal exception responses. Those default view functions have been removed, replaced with a generic default view function which is registered at Configurator setup for the ``repoze.bfg.interfaces.IExceptionResponse`` interface that simply returns the exception instance; the ``NotFound` and ``Forbidden`` classes are now still exception factories but they are also response factories which generate instances that implement the new ``repoze.bfg.interfaces.IExceptionResponse`` interface. --- repoze/bfg/exceptions.py | 68 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 13 deletions(-) (limited to 'repoze/bfg/exceptions.py') diff --git a/repoze/bfg/exceptions.py b/repoze/bfg/exceptions.py index 00cb76883..9b885d9dc 100644 --- a/repoze/bfg/exceptions.py +++ b/repoze/bfg/exceptions.py @@ -1,7 +1,43 @@ from zope.configuration.exceptions import ConfigurationError as ZCE +from zope.interface import implements -class Forbidden(Exception): - """\ +from repoze.bfg.decorator import reify +from repoze.bfg.interfaces import IExceptionResponse +import cgi + +class ExceptionResponse(Exception): + """ Abstract class to support behaving as a WSGI response object """ + implements(IExceptionResponse) + status = None + + def __init__(self, message=''): + Exception.__init__(self, message) # B / C + self.message = message + + @reify # defer execution until asked explicitly + def app_iter(self): + return [ + """ + + %s + +

%s

+ %s + + + """ % (self.status, self.status, cgi.escape(self.message)) + ] + + @reify # defer execution until asked explicitly + def headerlist(self): + return [ + ('Content-Length', str(len(self.app_iter[0]))), + ('Content-Type', 'text/html') + ] + + +class Forbidden(ExceptionResponse): + """ Raise this exception within :term:`view` code to immediately return the :term:`forbidden view` to the invoking user. Usually this is a basic ``401`` page, but the forbidden view can be @@ -11,10 +47,12 @@ class Forbidden(Exception): which should be a string. The value of this string will be placed into the WSGI environment by the router under the ``repoze.bfg.message`` key, for availability to the - :term:`Forbidden View`.""" + :term:`Forbidden View`. + """ + status = '401 Unauthorized' -class NotFound(Exception): - """\ +class NotFound(ExceptionResponse): + """ Raise this exception within :term:`view` code to immediately return the :term:`Not Found view` to the invoking user. Usually this is a basic ``404`` page, but the Not Found view can be @@ -24,7 +62,18 @@ class NotFound(Exception): which should be a string. The value of this string will be placed into the WSGI environment by the router under the ``repoze.bfg.message`` key, for availability to the :term:`Not Found - View`.""" + View`. + """ + status = '404 Not Found' + +class PredicateMismatch(NotFound): + """ + Internal exception (not an API) raised by multiviews when no + view matches. This exception subclasses the ``NotFound`` + exception only one reason: if it reaches the main exception + handler, it should be treated like a ``NotFound`` by any exception + view registrations. + """ class URLDecodeError(UnicodeDecodeError): """ @@ -41,10 +90,3 @@ class ConfigurationError(ZCE): """ Raised when inappropriate input values are supplied to an API method of a :term:`Configurator`""" -class PredicateMismatch(NotFound): - """ Internal exception (not an API) raised by multiviews when no - view matches. This exception subclasses the ``NotFound`` - exception only one reason: if it reaches the main exception - handler, it should be treated like a ``NotFound`` by any exception - view registrations.""" - -- cgit v1.2.3