2 votes

Comment renvoyer les détails de l'erreur Flask-SqlAlchemy ?

J'utilise Flask 1.0 , Flask-SqlAlchemy 2 y Angular 7 .

Lorsque SqlAlchemy génère une erreur, je souhaite afficher un message d'erreur personnalisé dans le frontend.

Il existe une section dans le la documentation officielle de Flask sur la manière de traiter les erreurs et également un question similaire ici sur SO, qui est lié à Sans flamme mais Et pourtant, je n'arrive pas à faire le lien.

Lorsque SqlAlchemy génère une erreur, cela ressemble à quelque chose comme ceci :

DETAIL:  Key (id)=(123) is not present in table "foo".

Je renvoie l'erreur à l'itinéraire :

try:
    db.session.commit()
except Exception as error:
    db.session.flush()
    db.session.rollback()
    return error

Dans la route, je vérifie s'il s'agit d'une erreur :

if status == True:
    return jsonify( { "success": True } ), 201
else:
    return error_response(500, str(status))

Et ma classe error_response ressemble à ceci :

def error_response(status_code, message=None):
    payload = {"error": HTTP_STATUS_CODES.get(status_code, "Unknown error")}
    if message:
        payload["message"] = message
        response = jsonify(payload)
        response.status_code = status_code
    return response

Mais la réponse json ne contient qu'un message d'erreur générique :

"message": "Http failure response for http://127.0.0.1:5000/database/add_foo: 0 Unknown Error"

2voto

Vous pouvez lire le error et créez votre propre message personnalisé à partir de celui-ci. Pour plus de détails, essayez d'imprimer error.\__dict__ dans la console.

erro.__dict__

par exemple :

from sqlalchemy import create_engine
from sqlalchemy import MetaData
from sqlalchemy import Table
from sqlalchemy import Column
from sqlalchemy import Integer, String

db_uri = 'sqlite:///'
engine = create_engine(db_uri)
conn = engine.connect()

# Create a metadata instance
meta = MetaData(engine)
table = Table('user', meta,
   Column('id', Integer, primary_key=True),
   Column('l_name', String),
   Column('f_name', String))
meta.create_all()
# Insert Data
conn.execute(table.insert(),[
   {'id':1,'l_name':'Hi','f_name':'bob'},
   {'id':2,'l_name':'Hello','f_name':'john'},
   {'id':3,'l_name':'yo','f_name':'bob-john'}])

result =conn.execute("SELECT * FROM user")
for res in result:
  print(res)
# Intensionally violating unique constraint
try:
  ins = table.insert().values(
      id=3,
      l_name='Hello',
      f_name='World')
# conn = engine.connect()
  conn.execute(ins)
except Exception as error:
  print(str(error.orig) + " for parameters" + str(error.params))

le résultat sera :-

Custom Exception Message

0voto

user3255061 Points 587

Il s'avère que l'erreur a été renvoyée lorsque j'ai essayé d'effectuer une sauvegarde groupée :

db.session.bulk_save_objects(companies_to_add, return_defaults = True)

J'avais l'impression qu'une erreur serait simplement soulevée lors de l'exécution de l'une ou l'autre des opérations suivantes

db.session.commit()

o

db.session.flush()

Apparemment, j'avais tort. Je place maintenant la sauvegarde en bloc dans un bloc d'essai :

try:
    db.session.bulk_save_objects(companies_to_add, return_defaults = True)
except Exception as error:
    db.session.rollback()
    return error

Je suis maintenant en mesure de détecter l'erreur dans le frontend.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X