如何让 Flask_restplus 使用来自 app_errorhandler 的错误处理程序?

How to get Flask_restplus to use error handlers from app_errorhandler?

我正在尝试在我的 API 中使用全局错误处理程序 (app_errorhandler),但我遇到了一些问题。 我有一个错误蓝图,我将全局错误定义为:

from werkzeug.exceptions import NotFound
from flask_app.errors import error_bp

@error_bp.app_errorhandler(NotFound)
def not_found_error(error):
    return "Error 404", 404

这适用于所有应用程序路由,但不适用于 flask_restplusflask_restful 创建的 API(都尝试过)。当我尝试在其中提高 NotFound 时,我得到:

"The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again. You have requested this URI [/user/info/1/] but did you mean /user/info// or /user/edit// or /user/login ?"

当我在 API 中定义一个 errorhandler 时:

@user_api.errorhandler(NotFound)
def new_error(error):
    return "Error handler in API 404"

它不在 API 中使用此 errorhandler,而是使用全局的(为什么?如何使用?),所以我找到了使用 app_errorhandler 的方法,但这不是解决方案因为如果我有全局设置,我不想为每个 API 定义一个 errorhandler。我所有的 API 都是使用它们所在的蓝图创建的。

所以我的问题是:如何在 API 中使用 app_errorhandler 而无需在每个 API 中定义 errorhandler

答案可以是 flask_restplus 或 flask_restful,因为我可以从一个切换到另一个。提前致谢。

注意: 有很多解决方法,但我认为默认情况下 apis 应该能够使用 apps 错误,因为 blueprints 可以使用它们并且 apis 继承 Blueprints

根据 Mehdi Sadeghi 要求的项目结构和代码:

.
|____flask_test_app
| |____errors
|   |___ __init__.py
|   |___ handlers.py
| |____test_found
|   |___ __init__.py
|   |___ apis.py
| |_____ __init__.py

__init__.py:

from flask import Flask

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config_name)

    from .errors import error_bp
    app.register_blueprint(error_bp)

    from .test_found import test_found
    app.register_blueprint(test_found)

    return app

errors.__init__.py:

from flask import Blueprint
error_bp = Blueprint('error_bp', import_name='error_bp')

from flask_test_app.errors import handlers

errors.handlers.py:

from werkzeug.exceptions import NotFound
from flask_test_app.errors import error_bp

@error_bp.app_errorhandler(NotFound)
def not_found_error(error):
    return "Error 404", 404

test_found.__init__py:

from flask import Blueprint
from flask_restplus import Api

test_found = Blueprint('test_found', import_name='test_found',
                       url_prefix='/test_found')

test_found_api = Api(test_found)
from flask_test_app.test_found import apis

test_found.apis.py:

from flask_restplus import Resource
from flask_test_app.test_found import test_found, test_found_api
from werkzeug.exceptions import NotFound

@test_found.route('/test_not_found', methods=['GET'])
def test_not_found():
    raise NotFound
    return "Not found does not work"

class TestAPINotFound(Resource):
    def get(self):
        raise NotFound
        return "TEST NOT FOUND FOR APIs"

test_found_api.add_resource(TestAPINotFound,
                      '/test_api_not_found',
                      endpoint='user_test')

在 flask-restful 中,如 the docs 中所述,您可以将 errors 字典传递给 api 并自定义返回的消息:

errors = {
    'NotFound': {
        'message': "Something is missing.",
        'status': 404,
    }
}

api = Api(app, errors=errors)

此外,它提供了 flask_restful.abort,您可以在 API:

中的任何地方使用
class HelloWorld(Resource):
    def get(self):
        if not self.has_permission():
            return flask_restful.abort(403)
        return {'hello': 'world'}

您还可以捕获异常,例如 NotFound 并使用 flask_restful.abort 如上所述。

但是,如果您确实需要自定义错误处理,您可以继承 Api 并在调用 flask_restful.abort:

之前实现您自己的错误处理
class CustomApi(Api):
    def handle_error(self, e):
        # Do something and then abort
        flask_restful.abort('some error code...', 'error message')

api = CustomApi(app, errors=errors)