Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么我的烧瓶错误处理程序没有被调用?_Python_Exception_Flask_Error Handling_Flask Restful - Fatal编程技术网

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

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

我正在尝试使用“”页面上的指导原则在Flask 1.0.2和Flask RESTful 0.3.7中创建自定义错误处理程序。(Flask RESTful有自己的方法,但由于它似乎没有办法在发生异常时接受定制的错误消息,因此我尝试使用vanilla Flask方法代替。)

调用只返回一条通用的“500 Internal Server Error”(500内部服务器错误)消息,但不会返回带有自定义错误文本的501错误。似乎
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')