flask-rest-jsonapi icon indicating copy to clipboard operation
flask-rest-jsonapi copied to clipboard

Unique handling SqlAlchemy

Open etiennecaldo opened this issue 8 years ago • 4 comments
trafficstars

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?

etiennecaldo avatar Nov 08 '17 14:11 etiennecaldo

I think its possible to "intercept" SQLAlchemy exceptions on the data layer using before_create_object or on create_object methods

hellupline avatar Nov 16 '17 03:11 hellupline

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.

etiennecaldo avatar Feb 22 '18 06:02 etiennecaldo

Yes of course you can suggest a PR

akira-dev avatar Jan 23 '19 16:01 akira-dev

@etiennecaldo Interesting issue. How do you imagine to implement that?

kumy avatar Jan 23 '19 18:01 kumy