summaryrefslogtreecommitdiff
path: root/docs/narr
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2016-09-19 23:52:05 -0500
committerMichael Merickel <michael@merickel.org>2016-09-28 20:33:27 -0500
commite8c66a339e9f7d83bd2408952de53ef30dba0794 (patch)
tree264643f1a6e45e0d3141c751b4724d51e49c0c5e /docs/narr
parent35209e4ac53520e1159bd8a6b47128f38a75db18 (diff)
downloadpyramid-e8c66a339e9f7d83bd2408952de53ef30dba0794.tar.gz
pyramid-e8c66a339e9f7d83bd2408952de53ef30dba0794.tar.bz2
pyramid-e8c66a339e9f7d83bd2408952de53ef30dba0794.zip
derive exception views separately from normal views
- previously the multiview was shared for both exception and hot-route, but now that we allow some exception-only views this needed to be separated - add ViewDeriverInfo.exception_only to detect exception views - do not prevent http_cache on exception views - optimize secured_view and csrf_view derivers to remove themselves from the view pipeline for exception views
Diffstat (limited to 'docs/narr')
-rw-r--r--docs/narr/hooks.rst23
-rw-r--r--docs/narr/viewconfig.rst19
-rw-r--r--docs/narr/views.rst40
3 files changed, 65 insertions, 17 deletions
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index 49ef29d3f..7fbac2080 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -1639,7 +1639,8 @@ the user-defined :term:`view callable`:
Enforce the ``permission`` defined on the view. This element is a no-op if no
permission is defined. Note there will always be a permission defined if a
default permission was assigned via
- :meth:`pyramid.config.Configurator.set_default_permission`.
+ :meth:`pyramid.config.Configurator.set_default_permission` unless the
+ view is an :term:`exception view`.
This element will also output useful debugging information when
``pyramid.debug_authorization`` is enabled.
@@ -1649,7 +1650,8 @@ the user-defined :term:`view callable`:
Used to check the CSRF token provided in the request. This element is a
no-op if ``require_csrf`` view option is not ``True``. Note there will
always be a ``require_csrf`` option if a default value was assigned via
- :meth:`pyramid.config.Configurator.set_default_csrf_options`.
+ :meth:`pyramid.config.Configurator.set_default_csrf_options` unless
+ the view is an :term:`exception view`.
``owrapped_view``
@@ -1695,6 +1697,8 @@ around monitoring and security. In order to register a custom :term:`view
deriver`, you should create a callable that conforms to the
:class:`pyramid.interfaces.IViewDeriver` interface, and then register it with
your application using :meth:`pyramid.config.Configurator.add_view_deriver`.
+The callable should accept the ``view`` to be wrapped and the ``info`` object
+which is an instance of :class:`pyramid.interfaces.IViewDeriverInfo`.
For example, below is a callable that can provide timing information for the
view pipeline:
@@ -1745,6 +1749,21 @@ View derivers are unique in that they have access to most of the options
passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what
to do, and they have a chance to affect every view in the application.
+.. _exception_view_derivers:
+
+Exception Views and View Derivers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A :term:`view deriver` has the opportunity to wrap any view, including
+an :term:`exception view`. In general this is fine, but certain view derivers
+may wish to avoid doing certain things when handling exceptions. For example,
+the ``csrf_view`` and ``secured_view`` built-in view derivers will not perform
+security checks on exception views unless explicitly told to do so.
+
+You can check for ``info.exception_only`` on the
+:class:`pyramid.interfaces.IViewDeriverInfo` object when wrapping the view
+to determine whether you are wrapping an exception view or a normal view.
+
Ordering View Derivers
~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst
index cd5b8feb0..76eaf3cc5 100644
--- a/docs/narr/viewconfig.rst
+++ b/docs/narr/viewconfig.rst
@@ -34,7 +34,7 @@ determine the set of circumstances which must be true for the view callable to
be invoked.
A view configuration statement is made about information present in the
-:term:`context` resource and the :term:`request`.
+:term:`context` resource (or exception) and the :term:`request`.
View configuration is performed in one of two ways:
@@ -306,9 +306,26 @@ configured view.
represented class or if the :term:`context` resource provides the represented
interface; it is otherwise false.
+ It is possible to pass an exception class as the context if your context may
+ subclass an exception. In this case **two** views will be registered. One
+ will match normal incoming requests and the other will match as an
+ :term:`exception view` which only occurs when an exception is raised during
+ the normal request processing pipeline.
+
If ``context`` is not supplied, the value ``None``, which matches any
resource, is used.
+``exception_only``
+
+ When this value is ``True`` the ``context`` argument must be a subclass of
+ ``Exception``. This flag indicates that only an :term:`exception view` should
+ be created and that this view should not match if the traversal
+ :term:`context` matches the ``context`` argument. If the ``context`` is a
+ subclass of ``Exception`` and this value is ``False`` (the default) then a
+ view will be registered to match the traversal :term:`context` as well.
+
+ .. versionadded:: 1.8
+
``route_name``
If ``route_name`` is supplied, the view callable will be invoked only when
the named route has matched.
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
index 770d27919..465062651 100644
--- a/docs/narr/views.rst
+++ b/docs/narr/views.rst
@@ -262,10 +262,16 @@ specialized views as described in :ref:`special_exceptions_in_callables` can
also be used by application developers to convert arbitrary exceptions to
responses.
-To register a view that should be called whenever a particular exception is
-raised from within :app:`Pyramid` view code, use the exception class (or one of
-its superclasses) as the :term:`context` of a view configuration which points
-at a view callable for which you'd like to generate a response.
+To register a :term:`exception view` that should be called whenever a
+particular exception is raised from within :app:`Pyramid` view code, use
+:meth:`pyramid.config.Configurator.add_exception_view` to register a view
+configuration which matches the exception (or a subclass of the exception) and
+points at a view callable for which you'd like to generate a response. The
+exception will be passed as the ``context`` argument to any
+:term:`view predicate` registered with the view as well as to the view itself.
+For convenience a new decorator exists,
+:class:`pyramid.views.exception_view_config`, which may be used to easily
+register exception views.
For example, given the following exception class in a module named
``helloworld.exceptions``:
@@ -277,17 +283,16 @@ For example, given the following exception class in a module named
def __init__(self, msg):
self.msg = msg
-
You can wire a view callable to be called whenever any of your *other* code
raises a ``helloworld.exceptions.ValidationFailure`` exception:
.. code-block:: python
:linenos:
- from pyramid.view import view_config
+ from pyramid.view import exception_view_config
from helloworld.exceptions import ValidationFailure
- @view_config(context=ValidationFailure)
+ @exception_view_config(ValidationFailure)
def failed_validation(exc, request):
response = Response('Failed validation: %s' % exc.msg)
response.status_int = 500
@@ -308,7 +313,7 @@ view registration:
from pyramid.view import view_config
from helloworld.exceptions import ValidationFailure
- @view_config(context=ValidationFailure, route_name='home')
+ @exception_view_config(ValidationFailure, route_name='home')
def failed_validation(exc, request):
response = Response('Failed validation: %s' % exc.msg)
response.status_int = 500
@@ -327,14 +332,21 @@ which have a name will be ignored.
.. note::
- Normal (i.e., non-exception) views registered against a context resource type
- which inherits from :exc:`Exception` will work normally. When an exception
- view configuration is processed, *two* views are registered. One as a
- "normal" view, the other as an "exception" view. This means that you can use
- an exception as ``context`` for a normal view.
+ In most cases, you should register an :term:`exception view` by using
+ :meth:`pyramid.config.Configurator.add_exception_view`. However, it is
+ possible to register 'normal' (i.e., non-exception) views against a context
+ resource type which inherits from :exc:`Exception` (i.e.,
+ ``config.add_view(context=Exception)``). When the view configuration is
+ processed, *two* views are registered. One as a "normal" view, the other
+ as an :term:`exception view`. This means that you can use an exception as
+ ``context`` for a normal view.
+
+ The view derivers that wrap these two views may behave differently.
+ See :ref:`exception_view_derivers` for more information about this.
Exception views can be configured with any view registration mechanism:
-``@view_config`` decorator or imperative ``add_view`` styles.
+``@exception_view_config`` decorator or imperative ``add_exception_view``
+styles.
.. note::