Python 如何让Flask_restplus从app_errorhandler使用错误处理程序?
我试图在我的API中使用全局错误处理程序(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 这适
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请查看您帖子下的我的评论。