Flask 中的 API——返回 JSON 但 HTML 异常破坏了我的 JSON 客户端
Posted
技术标签:
【中文标题】Flask 中的 API——返回 JSON 但 HTML 异常破坏了我的 JSON 客户端【英文标题】:API in Flask--returns JSON but HTML exceptions break my JSON client 【发布时间】:2012-11-26 06:25:04 【问题描述】:html 中返回的异常会破坏我的 JSON 客户端。我想jsonify这个输出。
更多细节:我有一个视图函数,它是这个 api 应用程序的端点。
如您所见,此函数以 json 格式返回结果。
@app.route('/route1')
def api_route1():
if user_id in request.args:
k1 = request.args['user_id']
return flask.jsonify(recs=some_function(k1))
else:
return "no valid user_id supplied"
问题,未处理的异常在 HTML 中,例如,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>TypeError: 'NoneType' object is not iterable // Werkzeug Debugger</title>
<link rel="stylesheet"
href="?__debugger__=yes&cmd=resource&f=style.css"
type="text/css">
这会破坏我的 json 客户端。 HTML 格式显然是默认格式,但我不知道如何选择退出并指定 jsonified 异常(理想情况下 jsonify 任何返回的甚至是标头)。
我怀疑我需要的是优秀的 Flask 文档中的某个地方,但我找不到它。
【问题讨论】:
所以您尝试保留错误消息并将它们作为 JSON 发送以防万一出现问题? @Blender,是的,这就是我想要的。 【参考方案1】:你应该定义 HTTP error handlers in flask.
一个简单的 JSON 返回 404 处理程序可能如下所示:
@app.errorhandler(404)
def page_not_found(e):
return flask.jsonify(error=404, text=str(e)), 404
有了这个,您将能够在客户端检查data.error
,如果存在,您可以使用 data.text 获取错误文本(作为e
传递的错误是werkzeug.exceptions.NotFound
,其字符串表示为“404 : 未找到”)。
【讨论】:
【参考方案2】:向 JSON 客户端提供回溯可能会泄露敏感信息。
我的建议是:
关闭调试 安装像sentry这样的日志聚合工具 使此应用程序的错误 500 页面返回 json 格式的一般错误500 页面可能如下所示:
"error": "500 - internal server error"
【讨论】:
这是 OP 应该做的。【参考方案3】:下面的代码应该可以解决问题。所以想法是捕获任何可能引发的异常,使用 traceback 模块将异常详细信息格式化为字符串,然后将其作为有效的 json 返回。我建议将一堆 except 语句与您期望发生的主要错误类型和更易读的错误消息一起放置。然后你可以有一个最后一个,除非发生一些奇怪和意想不到的事情。
import traceback
@app.route('/route1')
def api_route1():
if user_id in request.args:
try:
k1 = request.args['user_id']
return flask.jsonify(recs=some_function(k1))
except:
return flask.jsonify(exception=traceback.format_exc())
else:
return flask.jsonify(exception="no valid user_id supplied")
【讨论】:
即使else部分也可以有jsonify,当user_id不在参数中时会再次返回html。 @Codeanu 好建议,我用你的建议更新了答案。以上是关于Flask 中的 API——返回 JSON 但 HTML 异常破坏了我的 JSON 客户端的主要内容,如果未能解决你的问题,请参考以下文章
Flask 学习-57.Flask-RESTX 定制返回统一的JSON格式
如何更改 Flask-peewee 中的 UserDoesNotExist SELECT 行为 - python & mysql
Keras 模型在本地运行良好,但无法在 Flask API 上运行
Flask 学习-6. jsonify()返回JSON格式数据