Python 为什么我的烧瓶错误处理程序没有被调用?
我正在尝试使用“”页面上的指导原则在Flask 1.0.2和Flask RESTful 0.3.7中创建自定义错误处理程序。(Flask RESTful有自己的方法,但由于它似乎没有办法在发生异常时接受定制的错误消息,因此我尝试使用vanilla Flask方法代替。) 调用只返回一条通用的“500 Internal Server Error”(500内部服务器错误)消息,但不会返回带有自定义错误文本的501错误。似乎Python 为什么我的烧瓶错误处理程序没有被调用?,python,exception,flask,error-handling,flask-restful,Python,Exception,Flask,Error Handling,Flask Restful,我正在尝试使用“”页面上的指导原则在Flask 1.0.2和Flask RESTful 0.3.7中创建自定义错误处理程序。(Flask RESTful有自己的方法,但由于它似乎没有办法在发生异常时接受定制的错误消息,因此我尝试使用vanilla Flask方法代替。) 调用只返回一条通用的“500 Internal Server Error”(500内部服务器错误)消息,但不会返回带有自定义错误文本的501错误。似乎MyGenericException被正确引发,但Flask似乎忽略了它 [2
MyGenericException
被正确引发,但Flask似乎忽略了它
[2019-05-08 17:09:18,409] ERROR in app: Exception on /testme [GET]
Traceback (most recent call last):
File "C:\Users\testuser\Envs\testenv\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\testuser\Envs\testenv\lib\site-packages\flask\app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\testuser\Envs\testenv\lib\site-packages\flask_restful\__init__.py", line 458, in wrapper
resp = resource(*args, **kwargs)
File "C:\Users\testuser\Envs\testenv\lib\site-packages\flask\views.py", line 88, in view
return self.dispatch_request(*args, **kwargs)
File "C:\Users\testuser\Envs\testenv\lib\site-packages\flask_restful\__init__.py", line 573, in dispatch_request
resp = meth(*args, **kwargs)
File "C:/Users/testuser/Documents/PyCharm Projects/TestApp/testapp.py", line 32, in get
raise MyGenericException('A generic error', status_code=505)
MyGenericException
@app.errorhandler
装饰器似乎已为自定义MyGenericeException
异常正确设置。为什么不用烧瓶处理
感谢所有能够提供帮助的人。我从这两个方面获得的关键信息是,如果您的路由是Flask RESTful路由,那么它将由
handle\u error()
处理,防止或自定义此路由的唯一方法是实现您自己的API类,并重写handle\u error()
跟进@dylanj.nz的答案,下面是我确定的方法。它允许Flask RESTful处理HTTPException
类型的异常,但将所有其他内容传递给默认(Flask)处理程序,在该处理程序中,可以在异常发生时指定自定义错误消息(如果需要,可以指定键/值项的整个JSON对象)
from flask_restful import Resource, Api as _Api, HTTPException
app = Flask(__name__)
# This new Exception will accept a message, a status code, and a
# payload of other values to be displayed as a JSON object
class FlaskGenericException(Exception):
status_code = 500 # default unless overridden
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
@app.errorhandler(FlaskGenericException)
def handle_flask_generic_error(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
# This overridden Flask-RESTful API class will keep Flask-RESTful
# from handling errors other than HTTPException ones.
class Api(_Api):
def error_router(self, original_handler, e):
# Override original error_router to only handle HTTPExceptions.
if self._has_fr_route() and isinstance(e, HTTPException):
try:
# Use Flask-RESTful's error handling method
return self.handle_error(e)
except Exception:
# Fall through to original handler (i.e. Flask)
pass
return original_handler(e)
api = Api(app)
class TestMe(Resource):
def get(self):
try:
ldapc = ldap.connection
except:
# message = first parameter. Other parameters come in as "payload"
raise FlaskGenericException('A generic error', status_code=505, payload={'user': 'John Doe', 'company': 'Foobar Corp.'})
api.add_resource(TestMe, '/testme', endpoint='TestMe')
可能重复?@dylanj.nz,不,这是关于Flask RESTful解决方案的讨论,我试图避免使用纯Flask错误处理程序。我从这个问题和文档中获得的关键信息是,如果您的路线是Flask RESTful,而您的路线是,它将由
handle\u error()处理。
,防止或定制这种情况的唯一方法是实现自己的API类,并重写handle\u error()
.Hmmm。我已经解释为Flask RESTful将截获400和500个错误,但不是(例如)我试图在上面的异常中提出的505错误。但也许它截获的比我想象的要多-我想我必须进行实验。嗯,菲伊。看起来Flask RESTful确实拦截了所有5xx错误,即使没有定义自定义处理程序。糟糕透了@dylanj.nz,如果你想把你的评论写进回答中,我会接受的。
from flask_restful import Resource, Api as _Api, HTTPException
app = Flask(__name__)
# This new Exception will accept a message, a status code, and a
# payload of other values to be displayed as a JSON object
class FlaskGenericException(Exception):
status_code = 500 # default unless overridden
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
@app.errorhandler(FlaskGenericException)
def handle_flask_generic_error(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
# This overridden Flask-RESTful API class will keep Flask-RESTful
# from handling errors other than HTTPException ones.
class Api(_Api):
def error_router(self, original_handler, e):
# Override original error_router to only handle HTTPExceptions.
if self._has_fr_route() and isinstance(e, HTTPException):
try:
# Use Flask-RESTful's error handling method
return self.handle_error(e)
except Exception:
# Fall through to original handler (i.e. Flask)
pass
return original_handler(e)
api = Api(app)
class TestMe(Resource):
def get(self):
try:
ldapc = ldap.connection
except:
# message = first parameter. Other parameters come in as "payload"
raise FlaskGenericException('A generic error', status_code=505, payload={'user': 'John Doe', 'company': 'Foobar Corp.'})
api.add_resource(TestMe, '/testme', endpoint='TestMe')