Python 如何让Flask_restplus从app_errorhandler使用错误处理程序?

Python 如何让Flask_restplus从app_errorhandler使用错误处理程序?,python,python-3.x,flask,flask-restful,flask-restplus,Python,Python 3.x,Flask,Flask Restful,Flask Restplus,我试图在我的API中使用全局错误处理程序(app\u 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 这适

我试图在我的API中使用全局错误处理程序(
app\u 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\u restplus
flask\u restful
创建的API(两者都尝试过)。当我试图在它们中提出
NotFound
时,我得到:

“在服务器上找不到请求的URL。如果您输入 请手动检查您的URL拼写,然后重试。您有 请求此URI[/user/info/1/],但您的意思是 /用户/信息//或/用户/编辑//或 /用户/登录名?”

当我在API中将
errorhandler
定义为:

@user_api.errorhandler(NotFound)
def new_error(error):
    return "Error handler in API 404"
它没有在API中使用这个
errorhandler
,而是全局的(为什么?如何?),所以我找到了一种使用
app\u errorhandler
的方法,但这不是一个解决方案,因为如果我有全局设置,我不想为每个API定义一个
errorhandler
。我所有的API都是使用它们所在的蓝图创建的

因此,我的问题是:如何在API中使用
app\u errorhandler
,而不在每个API中定义
errorhandler

答案可以是flask_restplus或flask_restful,因为我在从一个切换到另一个方面没有问题。提前谢谢

注意: 有很多解决方法,但我认为
api
s应该能够默认使用
app
s错误,因为
blueprints
可以使用它们,而
api
s继承了蓝图

项目结构和代码符合Mehdi Sadeghi要求:

.
|____flask_test_app
| |____errors
|   |___ __init__.py
|   |___ handlers.py
| |____test_found
|   |___ __init__.py
|   |___ apis.py
| |_____ __init__.py
\uuuu init\uuuuu.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
from flask import Blueprint
error_bp = Blueprint('error_bp', import_name='error_bp')

from flask_test_app.errors import handlers
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
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
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')
错误。\uuuuu init\uuuuuuuuuuuupy

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
from flask import Blueprint
error_bp = Blueprint('error_bp', import_name='error_bp')

from flask_test_app.errors import handlers
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
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
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')
errors.handlers.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
from flask import Blueprint
error_bp = Blueprint('error_bp', import_name='error_bp')

from flask_test_app.errors import handlers
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
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
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')
找到测试。\uuuuu init\uuuuu 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
from flask import Blueprint
error_bp = Blueprint('error_bp', import_name='error_bp')

from flask_test_app.errors import handlers
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
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
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')
test\u found.api.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
from flask import Blueprint
error_bp = Blueprint('error_bp', import_name='error_bp')

from flask_test_app.errors import handlers
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
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
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中,如中所述,您可以将
错误
字典传递给api,并自定义返回的消息:

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

api = Api(app, errors=errors)
此外,它还提供了
flask\u restful.abort
,您可以在API中的任何位置使用:

class HelloWorld(Resource):
    def get(self):
        if not self.has_permission():
            return flask_restful.abort(403)
        return {'hello': 'world'}
您还可以捕获异常,例如
NotFound
,并如上所述使用
flask\u restful.abort

但是,如果确实需要自定义错误处理,则可以在调用
flask\u restful.abort
之前将
Api子类化并实现自己的错误处理:

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)

如果出现
flask\u restplus
问题,我无法重现您的问题。当我将事件处理程序添加到我最顶层的
api
时,它会被调用以处理所有api错误。也许你可以分享你的初始化代码,我会再试一次。@MehdiSadeghi我已经添加了我项目的结构。这可能会对你有所帮助。我建议你重新考虑你的设计。如果您为每个蓝图创建一个Api实例,那么最终将得到多个根Api端点。您可以将资源子类保留在blueprint包中,并将它们导入到
create_app
factory方法中,然后将它们添加到单个顶级
api
实例中。然后,您只需使用
api.errorhandler
添加全局api错误处理程序。如果您将错误处理程序直接添加到flask应用程序而不是蓝图中,会发生什么情况?谢谢您的回答,但这并不能解决问题。我知道您可以在
flask\u restful
中传递错误,很抱歉没有将其添加到中问题。这并不能解决这个问题,因为我想用
app\u errorhandler
定义错误,之后就不用担心了(不是在每个api中都定义)
api
s应该能够使用
app
s错误,因为
Blueprint
s可以使用它们和
api
s并继承
Blueprints
@kemis请查看您帖子下的我的评论。