Exceptions, HTTP Errors, and Redirects

Issuing redirects and HTTP errors

以下是与 Pylons 相比,如何发送 Pyramid 中的重定向和HTTP错误:

 1# Pylons -- in controller action
 2from pylons.controllers.util import abort, redirect
 3abort(404)   # Not Found
 4abort(403)   # Forbidden
 5abort(400)   # Bad request; e.g., invalid query parameter
 6abort(500)   # Internal server error
 7redirect(url("section1"))   # Redirect (default 302 Found)
 8
 9# Pyramid -- in view code
10import pyramid.httpexceptions as exc
11raise exc.exception_response(404)   # Not Found
12raise exc.HTTPNotFound()            # Same thing
13return exc.HTTPNotFound()           # Same thing
14raise exc.HTTPForbidden()
15raise exc.HTTPBadRequest()
16raise exc.HTTPInternalServerError()
17raise exc.HTTPFound(request.route_url("section1"))   # Redirect

这个 pyramid.httpexceptions 模块具有用于所有正式HTTP状态的类。这些类继承自 ResponseException ,所以你要么把它们还回去,要么把它们养大。引发HTTP异常可以使代码在结构上更具可读性。它在子程序中特别有用,在子程序中,它可以剪切几个调用堆栈帧,否则每个调用堆栈帧都需要 if to pass the error condition through.

Exception rules:

  1. Pyramid 内部提升 HTTPNotFound if no route matches the request, or if no view matches the route and request. 它提出 HTTPForbidden 如果请求基于当前授权策略被拒绝。

  2. If an uncaught exception occurs during request processing, Pyramid will catch it and look for an "exception view" that matches it. An exception view is one whose context argument is the exception's class, an ancestor of it, or an interface it implements. All other view predicates must also match; e.g., if a 'route_name' argument is specified, it must match the actual route name. (Thus an exception view is typically registered without a route name.) The view is called with the exception object as its 语境, 视图返回的任何响应都将发送到浏览器。因此,您可以使用异常视图自定义显示给用户的错误屏幕。

  3. 如果没有找到匹配的异常视图,则HTTP异常是它们自己的响应,因此它们被发送到浏览器。标准的httpexceptions有一个简单的错误消息和布局;子类可以自定义它。

  4. 非httpException响应传播到wsgi服务器。如果启用调试工具栏tween,它将捕获异常并显示交互式跟踪。否则,wsgi服务器将捕获它并发送自己的“500内部服务器错误”屏幕。

以下是最流行的HTTP异常:

等级

代码

位置

意义

HTTPMovedPermanently

301

Y

永久重定向;客户机应该更改书签。

HTTPFound

302

Y

Temporary redirect. [1]

HTTPSeeOther

303

Y

Temporary redirect; client should use GET. [1]

HTTPTemporaryRedirect

307

Y

Temporary redirect. [1]

HTTPClientError

400

N

General user error; e.g., invalid query param.

HTTPUnauthorized

401

N

用户必须进行身份验证。

HTTPForbidden

403

N

授权失败或一般拒绝。

HTTPNotFound

404

N

The URL is not recognized.

HTTPGone

410

N

以前位于此URL的资源将永久消失;客户端应删除书签。

HTTPInternalServerError

500

N

由于内部错误,服务器无法处理请求。

location列中带有“y”的类的构造函数参数为 (location="", detail=None, headers=None, comment=None, ...) . Otherwise the constructor args are (detail=None, headers=None, comment=None, ...) .

这个 location argument is optional at the Python level, but the HTTP spec requires a location that's an absolute URL, so it's effectively required.

这个 detail argument may be a plain-text string which will be incorporated into the error screen. headers may be a list of HTTP headers (name-value tuples) to add to the response. comment may be a plain-text string which is not shown to the user. (XXX Is it logged?)

异常视图

You can register an exception view for any exception class, although it's most commonly used with HTTPNotFoundHTTPForbidden . Here's an example of an exception view with a custom exception, borrowed from the Pyramid manual:

 1from pyramid.response import Response
 2
 3class ValidationFailure(Exception):
 4    pass
 5
 6@view_config(context=ValidationFailure)
 7def failed_validation(exc, request):
 8    # If the view has two formal arguments, the first is the context.
 9    # The context is always available as ``request.context`` too.
10    msg = exc.args[0] if exc.args else ""
11    response =  Response('Failed validation: %s' % msg)
12    response.status_int = 500
13    return response

For convenience, Pyramid has special decorators and configurator methods to register a "Not Found" view or a "Forbidden" view. @notfound_view_config@forbidden_view_config (定义在 pyramid.view ) takes care of the context argument for you.

此外, @notfound_view_config 接受一个 append_slash argument, which can be used to enforce a trailing-slash convention. If your site defines all its routes to end in a slash and you set append_slash=True , then when a slashless request doesn't match any route, Pyramid try again with a slash appended to the request URL. 如果 that 匹配一个路由, Pyramid 将向它发出重定向。这只适用于喜欢尾随斜杠(“/dir”和“/dir/a/”)的网站。其他网站喜欢 not 要有一个尾随斜杠(“/dir”和“/dir/a”),并且没有特殊的特性。

参考文献