Подтвердить что ты не робот

Пользовательское сообщение об ошибке json object с фляжкой

Легко распространять сообщения об ошибках с помощью фляжки-клиента для клиента с помощью метода abort(), например

abort(500, message="Fatal error: Pizza the Hutt was found dead earlier today
in the back seat of his stretched limo. Evidently, the notorious gangster
became locked in his car and ate himself to death.")

Это приведет к созданию следующего выхода json

{
  "message": "Fatal error: Pizza the Hutt was found dead earlier today
       in the back seat of his stretched limo. Evidently, the notorious gangster
       became locked in his car and ate himself to death.", 
  "status": 500
}

Есть ли способ настроить выход json с дополнительными членами? Например:

{
  "sub_code": 42,
  "action": "redirect:#/Outer/Space"
  "message": "You idiots! These are not them! You've captured their stunt doubles!", 
  "status": 500
}
4b9b3361

Ответ 1

Люди склонны злоупотреблять abort(), в то время как на самом деле очень просто создавать свои собственные ошибки. Вы можете написать функцию, которая легко генерирует пользовательские ошибки, вот что соответствует вашему JSON:

def make_error(status_code, sub_code, message, action):
    response = jsonify({
        'status': status_code,
        'sub_code': sub_code,
        'message': message,
        'action': action
    })
    response.status_code = status_code
    return response

Затем вместо вызова abort() сделайте следующее:

@route('/')
def my_view_function():
    # ...
    if need_to_return_error:
        return make_error(500, 42, 'You idiots!...', 'redirect...')
    # ...

Ответ 2

У меня нет репутации 50, чтобы комментировать @dappiu, поэтому мне просто нужно написать новый ответ, но это действительно связано с тем, что "Flask-RESTful удалось обеспечить более чистый способ обработки ошибок" как очень плохо документировано здесь

Это такой плохой документ, который заставил меня разобраться, как его использовать. Ключ вашего пользовательского исключения должен наследовать от flask_restful import HTTPException. Обратите внимание, что вы не можете использовать исключение Python.

from flask_restful import HTTPException

class UserAlreadyExistsError(HTTPException):
    pass

custom_errors = {
    'UserAlreadyExistsError': {
        'message': "A user with that username already exists.",
        'status': 409,
    }
}

api = Api(app, errors=custom_errors)

Команда Flask-RESTful сделала хорошую работу, чтобы упростить обработку пользовательских исключений, но документация разрушила усилия.

Ответ 3

Код @Miguel - это то, что вы должны использовать большую часть времени: никаких исключений, просто верните ответ в ветки обработчика запроса. Однако, если вам действительно нужен механизм прерывания, который вызывает исключение (это может быть полезно, например, в методах фильтрации), обратите внимание, что flask.abort принимает объект Response (проверьте gist):

from flask import abort, make_response, jsonify
abort(make_response(jsonify(message="Message goes here"), 400))

Ответ 4

Мне пришлось определить атрибут code для моего подкласса HttpException для правильной работы этой настраиваемой обработки ошибок:

from werkzeug.exceptions import HTTPException
from flask_restful import Api
from flask import Blueprint

api_bp = Blueprint('api',__name__)

class ResourceAlreadyExists(HTTPException):
    code = 400

errors = {
    'ResourceAlreadyExists': {
        'message': "This resource already exists.",
        'status': 409,
    },
}

api = Api(api_bp, errors=errors)

а затем, поднимите исключение

raise ResourceAlreadyExists

Ответ 5

Очевидно, что поздно, но в то время Flask-RESTful удалось обеспечить более чистый способ обработки ошибок, как указано docs.

Также открыт issue, чтобы предлагать, что улучшение может помочь.

Ответ 6

Здесь действительно простая и понятная основная функция. Это похоже на @Miguel's, но оно менее специализировано и соответствует согласованному с Flask использованию abort(). Использование исключений для потока управления не является антишаблоном в Python и на самом деле приветствуется. Таким образом, можно утверждать, что чаще следует использовать исключение, а не возвращать его, тем более что в структуре есть непредвиденные обстоятельства.

 def json_abort(status_code, data=None):
    if data is None:
        data = {}
    response = jsonify(data)
    response.status_code = status_code
    abort(response)

# then somewhere in your app during a request
json_abort(404, {'error': 'Not Found'}) 

Теперь вы можете расширять и настраивать его по своему усмотрению.