tipos - python try except pass
Controlador de error global para cualquier excepción (5)
¿Hay alguna manera de agregar un controlador de errores global de captura en la cual pueda cambiar la respuesta a una respuesta JSON genérica?
No puedo usar la señal got_request_exception
, ya que no está permitido modificar la respuesta ( http://flask.pocoo.org/docs/0.10/signals/ ).
En contraste, todos los manejadores de señales se ejecutan en un orden indefinido y no modifican ningún dato.
Preferiría no ajustar la función app.handle_exception
ya que se siente como una API interna. Supongo que estoy buscando algo como:
@app.errorhandler()
def handle_global_error(e):
return "Global error"
Tenga en cuenta que el errorhandler
no toma ningún parámetro, lo que significa que capturaría todas las excepciones / códigos de estado que no tienen un manejador de errores específico adjunto. Sé que puedo usar errorhandler(500)
o errorhandler(Exception)
para detectar excepciones, pero si abort(409)
por ejemplo, todavía devolverá una respuesta HTML.
Esto es compatible con Flask 0.12, y es una muy buena solución al problema (permite que uno reproduzca errores en JSON o en cualquier otro formato)
from functools import wraps
from flask import Flask, redirect, jsonify
app = Flask(__name__)
def get_http_exception_handler(app):
"""Overrides the default http exception handler to return JSON."""
handle_http_exception = app.handle_http_exception
@wraps(handle_http_exception)
def ret_val(exception):
exc = handle_http_exception(exception)
return jsonify({''code'':exc.code, ''message'':exc.description}), exc.code
return ret_val
# Override the HTTP exception handler.
app.handle_http_exception = get_http_exception_handler(app)
https://github.com/pallets/flask/issues/671#issuecomment-12746738
Lejos de ser elegante, pero lo siguiente funciona para vincular todas las subclases de HTTPException
a un único controlador de errores:
from flask import jsonify
from werkzeug.exceptions import HTTPException
def handle_error(error):
code = 500
if isinstance(error, HTTPException):
code = error.code
return jsonify(error=''error'', code=code)
for cls in HTTPException.__subclasses__():
app.register_error_handler(cls, handle_error)
Puede usar @app.errorhandler(Exception)
:
Demostración (la comprobación HTTPException garantiza que el código de estado se conserva):
from flask import Flask, abort, jsonify
from werkzeug.exceptions import HTTPException
app = Flask(''test'')
@app.errorhandler(Exception)
def handle_error(e):
code = 500
if isinstance(e, HTTPException):
code = e.code
return jsonify(error=str(e)), code
@app.route(''/'')
def index():
abort(409)
app.run(port=1234)
Salida:
$ http get http://127.0.0.1:1234/
HTTP/1.0 409 CONFLICT
Content-Length: 31
Content-Type: application/json
Date: Sun, 29 Mar 2015 17:06:54 GMT
Server: Werkzeug/0.10.1 Python/3.4.3
{
"error": "409: Conflict"
}
$ http get http://127.0.0.1:1234/notfound
HTTP/1.0 404 NOT FOUND
Content-Length: 32
Content-Type: application/json
Date: Sun, 29 Mar 2015 17:06:58 GMT
Server: Werkzeug/0.10.1 Python/3.4.3
{
"error": "404: Not Found"
}
Si también desea anular las excepciones HTML predeterminadas de Flask (para que también devuelvan JSON), agregue lo siguiente antes de app.run
:
from werkzeug.exceptions import default_exceptions
for ex in default_exceptions:
app.register_error_handler(ex, handle_error)
Para versiones anteriores de Flask (<= 0.10.1, es decir, cualquier versión no git / master en este momento), agregue el siguiente código a su aplicación para registrar los errores HTTP explícitamente:
from werkzeug import HTTP_STATUS_CODES
for code in HTTP_STATUS_CODES:
app.register_error_handler(code, handle_error)
Si las excepciones no funcionan, puede probar app.register_error_handler (o usar app.errorhandler de una manera que no sea decoradora)
Una forma más limpia de implementar esto en Flask> = 0.12 sería registrar explícitamente el controlador para cada excepción de Werkzeug:
from flask import jsonify
from werkzeug.exceptions import HTTPException, default_exceptions
app = Flask(''test'')
def handle_error(error):
code = 500
if isinstance(error, HTTPException):
code = error.code
return jsonify(error=''error'', code=code)
for exc in default_exceptions:
app.register_error_handler(exc, error_handler)