为什么我的Flask错误处理程序没有被调用?

2024-10-02 16:31:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试在Flask1.0.2和FlaskRestful0.3.7中创建一个自定义错误处理程序,使用“Implementing API Exceptions”页面上的指导原则。(Flask RESTful有自己的方法creating custom error messages,但是由于在异常发生时它似乎没有接受自定义错误消息的方法,所以我尝试使用vanilla Flask方法。)

from flask import Flask, jsonify
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

#########################################

class MyGenericException(Exception):
    status_code = 500
    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(MyGenericException)
def handle_generic_error(error):
    response = jsonify(error.to_dict())
    response.status_code = error.status_code
    return response

#########################################

class TestMe(Resource):
    def get(self):
        raise MyGenericException('A generic error', status_code=501)
api.add_resource(TestMe, '/testme', endpoint='TestMe')

#########################################

if __name__ == '__main__':
    app.run(debug=False)

调用http://127.0.0.1:5000/testme只返回一个通用的“500内部服务器错误”消息,而不是带有自定义错误文本的501错误。似乎MyGenericException被正确地举起,但烧瓶似乎忽略了它。在

^{pr2}$

@app.errorhandler修饰符似乎为自定义MyGenericException异常正确设置。为什么不用烧瓶处理?在

感谢任何能帮忙的人。在


Tags: 方法selfnoneappflaskmessagedefstatus
2条回答

跟进@新西兰迪兰杰的答案是,this vanilla-Flask error handling method,和{a2},这是我决定的方法。{JSON{else>允许在指定的时候通过一个自定义的异常值来处理所有的异常。在

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')

引用this questiondocs,我从这两者中获得的关键信息是,如果您的路由是Flask RESTful路径,那么它将由handle_error()处理,而防止或定制这一点的唯一方法是实现自己的API类,并重写handle_error()。在

相关问题 更多 >