Python WSGI处理抛出异常

在WSGI处理期间抛出异常,WSGI应用程序的一个核心特性是链上的每个阶段都会负责过滤请求。其思想是在处理过程中尽早拒绝错误的请求。Python的异常处理使这一点易于实现。

可以定义一个提供静态内容的WSGI应用程序,如下所示:

def static_app(
        environ: Dict,
        start_response: SR_Func
    ) -> Union[Iterator[bytes], List[bytes]]:
    log = environ['wsgi.errors']
    try:
        print(f"CWD={Path.cwd()}", file=log)
        static_path = Path.cwd()/environ['PATH_INFO'][1:]
        with static_path.open() as static_file:
            content = static_file.read().encode("utf-8")
            headers = [
                ("Content-Type", 'text/plain;charset="utf-8"'),
                ("Content-Length", str(len(content))),
            ]
            start_response('200 OK', headers)
            return [content]
    except IsADirectoryError as e:
        return index_app(environ, start_response)
    except FileNotFoundError as e:
    start_response('404 NOT FOUND', [])
    return [
        f"Not Found {static_path}\n{e!r}".encode("utf-8")
    ]

该应用程序从当前工作目录中创建了一个Path对象,以及一个作为请求URL一部分而提供的路径元素。路径信息是WSGI环境的一部分,位于以PATH_INFO'为键的项中。正是由于这种解析路径的方式,因此它会有一个前导的/,我们使用environ['PATH_INFO][1:]来丢弃该字符。

该应用程序尝试将请求的路径以文本文件的形式打开。这里有两个常见问题,会将它们作为异常来处理:

  • 如果文件是一个目录,将使用另一个应用程序index_app来呈现目录内容;
  • 如果没有找到该文件,将返回一个HTTP 404 NOT FOUND响应。

该WSGI应用程序引发的其他任何异常都不会被捕获。应把调用该应用程序的程序设计为具有某种通用的错误响应能力。如果应用程序不处理这些异常,则会使用通用的WSGI故障响应。

上面的处理涉及严格的运算顺序。必须读取整个文件才能创建一个正确的HTTP Content-Length报头。

处理异常有两种方式。一种是调用另一个应用程序。如果需要向该应用程序提供额外信息,则必须使用所需的信息来更新环境。这便是为一个复杂网站构建标准化错误页面的方法。

另一种是调用start_response()函数并返回一个错误结果,这适用于特定的本地化行为。最终的内容以字节形式呈现,这意味着必须将Python字符串正确编码,且必须向用户代理提供编码信息,甚至在错误信息repr(e)被下载之前就应该已经正确编码。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程