flask-rest-jsonapi
flask-rest-jsonapi copied to clipboard
Unique handling SqlAlchemy
Hello, Thank you for your great work. I am integrating flask-rest-jsonapi into my project and I have a question for you. I use Flask-SqlAlchemy and have a model with a "unique" field.
When I try to create an object twice, this is the answer I get:
{ "errors": [ { "detail": "Object creation error: (psycopg2.IntegrityError) duplicate key value violates unique constraint "user_email_key" DETAIL: Key (email)=([email protected]) already exists. [SQL: 'INSERT INTO "user" ("firstName", "lastName", email, password, active, "createdAt", "group") VALUES (%(firstName)s, %(lastName)s, %(email)s, %(password)s, %(active)s, %(createdAt)s, %(group)s) RETURNING "user".id'] [parameters: {'firstName': 'toto', 'lastName': 'toto', 'email': '[email protected]', 'password': '$2b$12$XnZZlBozAcMP12ZnOjsP4.i3ftCOYTNLw9EnbsvZQtRSRYYXlldf6', 'active': False, 'createdAt': datetime.datetime(2017, 11, 8, 14, 39, 49, 244605), 'group': 'S'}]", "source": { "pointer": "/data" }, "status": 500, "title": "Unknown error" } ], "jsonapi": { "version": "1.0" } }
I get the error raised by SqlAlchemy as error description, and a 500 status. How would it be possible to catch this exception and send a more human-friendly JsonApiException?
I think its possible to "intercept" SQLAlchemy exceptions on the data layer
using before_create_object or on create_object methods
Hi, Thank you for your answer!
Hum I looked at flask_rest_jsonapi/data_layers/alchemy.py and it seems like the exception is raised during the self.session.commit (line 53), and catched immediately and reraised as JsonApiAxception. So it is raised after the before_create_object.
And create_object itself is not part of the REWRITABLE_METHODS listed in flask_rest_jsonapi/data_layers/base.py
What annoys me is the long message that I can't display on frontend but also the 500 status code which is not representative. It should perhaps be like a ValidationError.
So I am kinda stuck here. I may workaround by checking object doesn't exist yet in before_create_object but it's something I will have to duplicate in every model I have.
Perhaps the best solution is to improve db.session.commit() exception handling. If we agree on a solution I might suggest a PR.
Yes of course you can suggest a PR
@etiennecaldo Interesting issue. How do you imagine to implement that?