restful - flask swagger
Mensaje de error personalizado objeto json con matraz-restful (6)
Es fácil propagar mensajes de error con el matraz en reposo al cliente con el método abort()
, como
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.")
Esto generará la siguiente salida 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
}
¿Hay alguna manera de personalizar la salida json con miembros adicionales? Por ejemplo:
{
"sub_code": 42,
"action": "redirect:#/Outer/Space"
"message": "You idiots! These are not them! You''ve captured their stunt doubles!",
"status": 500
}
Aquí hay una función básica muy simple y limpia. Es similar a la de @Miguel, pero es menos especializado y se mantiene consistente con el uso previsto de Flask de abort()
. El uso de excepciones para el flujo de control no es un antipatrón en Python y en realidad se recomienda. Por lo tanto, se podría argumentar que aumentar la excepción en lugar de devolverla debería ser lo más a menudo posible, especialmente porque el marco tiene contingencias para ellos.
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''})
Ahora puedes ampliarlo y personalizarlo como quieras.
El código de @Miguel es lo que debería usar la mayor parte del tiempo: sin excepciones, solo devuelva una respuesta en una rama del controlador de solicitudes. Sin embargo, si realmente necesita un mecanismo de flask.abort que flask.abort una excepción (esto puede ser útil en métodos de filtro, por ejemplo), tenga en cuenta que flask.abort acepta un objeto de Response (verifique esta información):
from flask import abort, make_response, jsonify
abort(make_response(jsonify(message="Message goes here"), 400))
Las personas tienden a abusar de abort()
, aunque en realidad es muy simple generar sus propios errores. Puede escribir una función que genere errores personalizados fácilmente, aquí hay una que coincide con su 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
Entonces en lugar de llamar a abort()
haz esto:
@route(''/'')
def my_view_function():
# ...
if need_to_return_error:
return make_error(500, 42, ''You idiots!...'', ''redirect...'')
# ...
No tengo una reputación de 50 para comentar en @dappiu, así que solo tengo que escribir una nueva respuesta, pero está realmente relacionada con "Flask-RESTful logró proporcionar una forma más limpia de manejar los errores" como está muy mal documentado aquí
Es un documento tan malo que me tomó un tiempo descubrir cómo usarlo. La clave es que su excepción personalizada debe heredarse de la excepción HTTPException de flask_restful import. Tenga en cuenta que no puede utilizar la excepción de 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)
El equipo de Flask-RESTful ha hecho un buen trabajo para facilitar el manejo personalizado de las excepciones, pero la documentación arruinó el esfuerzo.
Tuve que definir un code
atributo para mi HttpException
subclasificada para que este manejo de errores personalizado funcione correctamente:
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)
y luego, levante la excepción.
raise ResourceAlreadyExists