try tipos sirve que print pass para imprimir exceptions excepciones error ejemplos diferentes catch all python error-handling flask http-error

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)



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)