flask - 为什么在使用 Response 实例调用 abort 时不调用 HTTPException 的处理程序?
问题描述
from flask import Flask, abort, Response
from werkzeug.exceptions import HTTPException
app = Flask(__name__)
@app.errorhandler(HTTPException)
def http_exception_handler(e: HTTPException):
msg = 'http_exception_handler is called.'
print(msg)
return msg
@app.route('/')
def index():
try:
abort(Response('I am the response passed to abort.', 400))
except Exception as e:
print(f'Raised error is an instance of HTTPException: {isinstance(e, HTTPException)}')
raise e
return 'Index successfully produced a response.'
在上面的代码中,为什么使用对象调用函数HTTPException
时注册的处理程序没有被调用?代码的执行表明引发的错误是.abort
Response
abort
HTTPException
解决方案
TL;DR:不要传递 Response 对象。如果要使用 ErrorHandler,请使用 HTTP 代码。
所以,它看起来更复杂。您可以深入研究 Werkzeug 代码和 Flask 以查看发生了什么。我不打算详细说明步骤。
因此,在 Aborter 类上调用 abort()。这将从您的 Response 对象创建一个 HTTPException。
如果您运行以下命令,您将拥有:
>>> print(HTTPException(response=Response("BODY",404)))
??? Unknown Error: None
此 HTTPException 没有代码。
>>> print(HTTPException(response=Response("BODY", 404)).code)
None
这个由错误处理程序解释。
def handle_http_exception(self, e):
if e.code is None:
return e # Here's your return
# This is never called.
handler = self._find_error_handler(e)
if handler is None:
return e
return handler(e)
然后你的处理程序装饰器将永远不会被调用。
所以这是详细步骤的一部分。但是因为 Flask 和 Werkzeug 的编码很好。您可以在此处直接阅读 HTTPException 类:
def get_response(self, environ=None):
"""Get a response object. If one was passed to the exception
it's returned directly.
就是这个意思,直接返回。这是有道理的。如果您已经管理了错误,为什么还要继续使用错误处理程序。
如果你想更深入地了解代码,这里有一些 github 链接:
推荐阅读
- angular - 布尔变量在角度中未定义
- python - 鸢尾花数据集上的变分自动编码器
- javascript - React Native Firebase 如何让自动文档 ID 增加 1
- c# - 如何在 Blazor WebAssembly 项目中使用 C# 9?
- swift - swift如何让列表从顶部开始而没有填充
- wpf - 如何检测 WPF WebView 控件的鼠标滚轮?
- xcode - 使用 SwiftUI 在 macOS 上阻止 FirebaseApp.configure() 的应用沙盒
- python - 如何将列表附加到另一个依赖于变量的列表以创建嵌套列表?
- css - 最多 2 个居中对齐的项目
- swift - 您可以将多个子路径作为单个路径,并且只填充一次吗?