错误处理

在本例中,我们将扩展动态分发,以便在客户端请求不存在的 URL 时返回 404(未找到)响应。

与之前的示例一样,我们将从 SiteResourcereactorendpoints 导入开始

from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints

接下来,我们将添加另一个导入。 notFound 是 Twisted Web 提供的预定义错误资源之一。它会生成必要的 404 响应代码,并呈现一个简单的 HTML 页面,告诉客户端没有这样的资源。

from twisted.web.pages import notFound

接下来,我们将定义一个自定义资源,它执行一些动态 URL 分发。本例将与 上一个示例 相同,其中路径段被解释为年份;不同之处在于,这次我们将处理不符合该模式的请求,并返回未找到的响应

class Calendar(Resource):
    def getChild(self, name, request):
        try:
            year = int(name)
        except ValueError:
            return notFound()
        else:
            return YearPage(year)

除了包含来自上一个示例的 YearPage 的定义之外,剩下的唯一要做的事情是正常的 Sitereactor 设置。以下是本例的完整代码

from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints
from twisted.web.pages import notFound

from calendar import calendar

class YearPage(Resource):
    def __init__(self, year):
        Resource.__init__(self)
        self.year = year

    def render_GET(self, request):
        cal = calendar(self.year)
        return (b"<!DOCTYPE html><html><head><meta charset='utf-8'>"
                b"<title></title></head><body><pre>" + cal.encode('utf-8') + b"</pre>")

class Calendar(Resource):
    def getChild(self, name, request):
        try:
            year = int(name)
        except ValueError:
            return notFound()
        else:
            return YearPage(year)

root = Calendar()
factory = Site(root)
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8880)
endpoint.listen(factory)
reactor.run()

此服务器提供与上一部分相同的日历视图,但它还会在请求的 URL 无法解释为年份时提供一个带有 404 响应的错误页面。