I would like to do some handler for exception. I'm using a combination of Flask-restless and SQLAlchemy in python.
My problem:
When I send request to api with object that already exists in DB, SQLAlchemy shows exception:
IntegrityError: (IntegrityError) column <column_name> is not unique u'INSERT INTO ...
So I have tried to add attribute validation_exceptions
into create_api
method:
manager.create_api( ... , validation_exceptions=[IntegrityError])
But response json contains:
{
"validation_errors": "Could not determine specific validation errors"
}
and server api shows exception :
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\flask_restless\views.py", line 797, in _extract_error_messages
left, right = str(exception).rsplit(':', 1)
ValueError: need more than 1 value to unpack
Exception validation in Flask-restless doesn't work with this type of exception (IntegrityError)
What should I do? Is it possible to create some handler for exception and to return my own error message in json?
The documentation (v0.17.0 to date of this posting) states:
Currently, Flask-Restless expects that an instance of a specified validation error will have a errors attribute, which is a dictionary mapping field name to error description (note: one error per field).
So to change the content of validation_errors
your exception needs an errors
attribute that contains a dictionary. The content of this dictionary will appear in the servers response as validation_errors
.
From flask-restless/tests/test_validation.py:
class TestSimpleValidation(ManagerTestBase):
"""Tests for validation errors raised by the SQLAlchemy's simple built-in
validation.
For more information about this functionality, see the documentation for
:func:`sqlalchemy.orm.validates`.
"""
def setup(self):
"""Create APIs for the validated models."""
super(TestSimpleValidation, self).setup()
class Person(self.Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
age = Column(Integer, nullable=False)
@validates('age')
def validate_age(self, key, number):
if not 0 <= number <= 150:
exception = CoolValidationError()
exception.errors = dict(age='Must be between 0 and 150')
raise exception
return number
@validates('articles')
def validate_articles(self, key, article):
if article.title is not None and len(article.title) == 0:
exception = CoolValidationError()
exception.errors = {'articles': 'empty title not allowed'}
raise exception
return article
class Article(self.Base):
__tablename__ = 'article'
id = Column(Integer, primary_key=True)
title = Column(Unicode)
author_id = Column(Integer, ForeignKey('person.id'))
author = relationship('Person', backref=backref('articles'))
self.Article = Article
self.Person = Person
self.Base.metadata.create_all()
self.manager.create_api(Article)
self.manager.create_api(Person, methods=['POST', 'PATCH'],
validation_exceptions=[CoolValidationError])
Request:
data = dict(data=dict(type='person', age=-1))
response = self.app.post('/api/person', data=dumps(data))
Response:
HTTP/1.1 400 Bad Request
{ "validation_errors":
{
"age": "Must be between 0 and 150",
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With