如何让 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_restplus
或 flask_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,因为我可以从一个切换到另一个。提前致谢。
注意:
有很多解决方法,但我认为默认情况下 api
s 应该能够使用 app
s 错误,因为 blueprints
可以使用它们并且 api
s 继承 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)
我正在尝试在我的 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_restplus
或 flask_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,因为我可以从一个切换到另一个。提前致谢。
注意:
有很多解决方法,但我认为默认情况下 api
s 应该能够使用 app
s 错误,因为 blueprints
可以使用它们并且 api
s 继承 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)