API в Flask - возвращает JSON, но исключения HTML нарушают мой клиент JSON
исключения, возвращаемые в HTML, разбивают мой клиент JSON. Я хочу изменить этот вывод.
Подробнее: у меня есть функция просмотра, которая является конечной точкой этого приложения 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 exceptions (и в идеале jsonify все возвращенные даже заголовки).
Я подозреваю, что мне нужно где-то в отличной документации по фляге, но я не могу ее найти.
Ответы
Ответ 1
Вы должны определить HTTP обработчики ошибок в колбе.
Простой обработчик JSON returing 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" }
Ответ 3
Код ниже должен сделать трюк. Таким образом, идея состоит в том, чтобы поймать любое исключение, которое могло быть поднято, получить детали исключения, отформатированные как строка, используя модуль трассировки, а затем вернуть это как действительный json. Я бы рекомендовал разместить кучу исключающих операторов с основными типами ошибок, которые вы ожидаете, и более читаемым сообщением об ошибке. Тогда у вас может быть один последний, кроме как поймать все на случай, если произойдет что-то странное и неожиданное.
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")
Ответ 4
Вы пробовали http://flask.pocoo.org/docs/patterns/errorpages/ для пользовательских страниц ошибок? Просто верните JSON с этим для ожидаемых кодов ошибок.