29

使用flask-restful的方法很容易将错误消息传播给客户端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
}
4

7 回答 7

43

人们倾向于过度使用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...')
    # ...
于 2014-02-07T23:19:17.097 回答
26

我对@dappiu 的评论没有 50 名声望,所以我只需要写一个新的答案,但它确实与“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 团队在简化自定义异常处理方面做得很好,但文档破坏了这项工作。

于 2015-09-08T03:59:38.860 回答
9

正如@Miguel 所示,通常你不应该使用异常,只返回一些错误响应。但是,有时您确实需要一个引发异常的中止机制。例如,这在过滤方法中可能很有用。请注意,flask.abort接受一个Response对象(检查此要点):

from flask import abort, make_response, jsonify

response = make_response(jsonify(message="Message goes here"), 400)
abort(response)
于 2017-07-07T10:25:48.103 回答
5

我不同意@Miguel 关于abort(). 除非您使用 Flask 构建 HTTP 应用程序以外的东西(使用请求/响应范例),否则我相信您应该尽可能多地使用HTTPExceptions(参见werkzeug.exceptions模块)。这也意味着使用中止机制(这只是这些异常的捷径)。相反,如果您选择在视图中显式构建并返回您自己的错误,则会导致您需要使用一系列 if/else/return 检查值的模式,这通常是不必要的。请记住,您的函数很可能在请求/响应管道的上下文中运行。不必在做出决定之前一直返回视图,只需在失败点中止请求并完成它即可。该框架完全理解这种模式并具有偶然性。如果需要,您仍然可以捕获异常(也许用其他消息补充它,或者挽救请求)。

因此,类似于@Miguel,但保留了预期的中止机制:

 def json_abort(status_code, data=None):
    response = jsonify(data or {'error': 'There was an error'})
    response.status_code = status_code
    abort(response)

# then in app during a request

def check_unique_username(username):
    if UserModel.by__username(username):
        json_abort(409, {'error': 'The username is taken'})

def fetch_user(user_id): 
    try:
        return UserModel.get(user_id)
    except UserModel.NotFound:
        json_abort(404, {'error': 'User not found'})
于 2018-07-02T23:35:00.953 回答
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
于 2016-07-12T02:06:41.293 回答
1

显然已经晚了,但与此同时,正如docs所指出的那样,Flask-RESTful 设法提供了一种更简洁的方式来处理错误。

此外,提出改进建议的问题也可以提供帮助。

于 2014-07-28T19:52:50.643 回答
0

使用 Flask-RESTful(0.3.8 或更高版本)

from flask_restful import Api
customErrors = {
    'NotFound': {
        'message': "The resource that you are trying to access does not exist",
        'status': 404,
        'anotherMessage': 'Another message here'
    },
    'BadRequest': {
        'message': "The server was not able to handle this request",
        'status': 400,
        'anotherMessage': 'Another message here'
    }
}
app = Flask(__name__)
api = Api(app, catch_all_404s=True, errors=customErrors)

诀窍是使用Werkzeug Docs中的异常

因此,例如,如果您想处理 400 请求,您应该将BadRequest添加到 customErrors json 对象。

或者如果你想处理 404 错误,那么在你的 json 对象中使用NotFound等等

于 2021-03-01T11:09:53.387 回答