Flask: API-обработчик ошибок выполняется два раза - PullRequest
0 голосов
/ 31 мая 2019

Я делаю проект Flask API, и у меня проблема с обработкой исключения AssertionError. Поэтому моя программа проверяет, является ли длина указанного параметра, и вызывает ошибку AssertionError, если длина превышает лимит. Проблема в том, что обработчик ошибок выполняется два раза.

__ __ INIT. Ру

from flask_restplus import Api
from flask import Blueprint

from .main.controller.book_controller import api as book_ns
from .main.controller.category_controller import api as category_ns

from .main.exception.not_found import NotFound

blueprint = Blueprint('api', __name__)

api = Api(blueprint,
          title='FLASK RESTPLUS API BOILER-PLATE WITH JWT',
          version='1.0',
          description='a boilerplate for flask restplus web service')

api.add_namespace(book_ns, path='/book')
api.add_namespace(category_ns, path='/category')


@api.errorhandler(NotFound)
def handle_no_result(error):
    '''Return a custom not found error message and 404 status code'''
    return {'message': error.message}, 404


@api.errorhandler(AssertionError)
def handle_assertion_error(error):
    '''Return the assertion error message and 400 status code'''
    print("&&&&&&&&&&&&&&&&&&")
    return {'message': error.message}, 400

book.py (модель)

from .. import db
from sqlalchemy.schema import Sequence
from sqlalchemy.orm import validates


class Book(db.Model):
    __tablename__ = 'book'

    book_id = db.Column('book_id',
                        db.Integer,
                        Sequence('seq_book'),
                        primary_key=True)
    viewable = db.Column('viewable', db.Integer)
    title = db.Column('title', db.String(length=50), nullable=False)
    isbn = db.Column('isbn', db.String(length=13), unique=True, nullable=False)
    publication_date = db.Column('publication_date', db.Date)
    presentation_month = db.Column('presentation_month', db.String(length=7))
    image = db.Column('image', db.String(length=100))
    category_id = db.Column('category_id', db.Integer,
                            db.ForeignKey('category.category_id'))

    category = db.relationship('Category')

    def __repr__(self):
        return '<id {}>'.format(self.book_id)

    def serialize(self):
        return {
            'book_id': int(self.book_id),
            'isbn': self.isbn,
            'title': self.title,
            'category': self.category.serialize(),
            'publication_date': self.publication_date,
            'presentation_month': self.presentation_month,
            'image': self.image
        }

    @validates('title')
    def validates_title(self, key, title):
        if not title:
            raise AssertionError('title cannot be blank')
        if len(title) > 50:
            raise AssertionError(
                'title length must be minor or equal to 50 characters')

    @validates('isbn')
    def validates_isbn(self, key, isbn):
        if not isbn:
            raise AssertionError('isbn cannot be blank')
        if len(isbn) > 13:
            raise AssertionError(
                'isbn length must be minor or equal to 13 characters')

    @validates('presentation_month')
    def validates_presentation_month(self, key, presentation_month):
        if len(presentation_month) > 7:
            raise AssertionError(
                'presentation_month length must be minor or equal to 7 characters'
            )

    @validates('image')
    def validates_image(self, key, image):
        if len(image) > 100:
            raise AssertionError(
                'image length must be minor or equal to 100 characters')

Таким образом, я получаю сообщение об ошибке исключения в консоли, она печатает два раза «&&&&&&&&&&&&&&&&&» и отправляет код состояния 500, а не de 400. Я думаю, что он выдает код ошибки 500, потому что он возвращает два раза return {'message': error.message}, 400 , Я понятия не имею, как решить эту проблему.

--- EDIT -----------------------------

Исключение, возвращаемое в консоли:

&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
127.0.0.1 - - [31/May/2019 11:21:53] "POST /book/ HTTP/1.1" 500 -
Traceback (most recent call last):
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2328, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2314, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_restplus\api.py", line 583, in error_router
    return original_handler(e)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1760, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 36, in reraise
    raise value
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2311, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1834, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_restplus\api.py", line 583, in error_router
    return original_handler(e)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1737, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 36, in reraise
    raise value
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1832, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1818, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_restplus\api.py", line 325, in wrapper
    resp = resource(*args, **kwargs)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\views.py", line 88, in view
    return self.dispatch_request(*args, **kwargs)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_restplus\resource.py", line 44, in dispatch_request
    resp = meth(*args, **kwargs)
  File "C:\Users\albert_lazaro\Documents\Projects\Generetis\generetis-backend-flask\app\main\controller\book_controller.py", line 33, in post
    return save_new_book(data=data)
  File "C:\Users\albert_lazaro\Documents\Projects\Generetis\generetis-backend-flask\app\main\service\book_service.py", line 28, in save_new_book
    viewable=0)
  File "<string>", line 4, in __init__

  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\state.py", line 441, in _initialize_instance
    manager.dispatch.init_failure(self, args, kwargs)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\util\langhelpers.py", line 68, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\util\compat.py", line 129, in reraise
    raise value
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\state.py", line 438, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\ext\declarative\base.py", line 836, in _declarative_constructor
    setattr(self, k, kwargs[k])
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\attributes.py", line 262, in __set__
    instance_state(instance), instance_dict(instance), value, None
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\attributes.py", line 822, in set
    state, dict_, value, old, initiator
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\attributes.py", line 830, in fire_replace_event
    state, value, previous, initiator or self._replace_token
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\util.py", line 168, in set_
    return validator(state.obj(), key, value)
  File "C:\Users\albert_lazaro\Documents\Projects\Generetis\generetis-backend-flask\app\main\model\book.py", line 52, in validates_isbn
    'isbn length must be minor or equal to 13 characters')
AssertionError: isbn length must be minor or equal to 13 characters
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...