8

Is there a way in Falcon framework to respond with HTTP 500 status on any unspecific exception that is not handled in resource handler? I've tried to add following handler for Exception:

api.add_error_handler(Exception, 
                      handler=lambda e, 
                      *_: exec('raise falcon.HTTPInternalServerError("Internal Server Error", "Some error")'))

But this makes impossible to throw, for example, falcon.HTTPNotFound — it is handled by the handler above and I receive 500 instead of 404.

4

3 回答 3

8

对的,这是可能的。您需要定义一个通用错误处理程序,检查异常是否是任何 falcon 错误的实例,如果不是,则引发 HTTP_500。

这个例子展示了一种方法。

def generic_error_handler(ex, req, resp, params):
    if not isinstance(ex, HTTPError):
        raise HTTPInternalServerError("Internal Server Error", "Some error")
    else:  # reraise :ex otherwise it will gobble actual HTTPError returned from the application code ref. https://stackoverflow.com/a/60606760/248616
        raise ex

app = falcon.API()
app.add_error_handler(Exception, generic_error_handler)
于 2018-09-23T09:48:35.580 回答
2

接受的答案似乎吞噬HTTPError了从应用程序代码返回的实际值。这对我有用:

def generic_error_handler(ex, req, resp, params):
    if not isinstance(ex, HTTPError):
        logger.exception("Internal server error")
        raise HTTPInternalServerError("Internal Server Error")
    else:
        raise ex

于 2020-03-09T18:59:24.353 回答
1

我不确定我是否正确理解了您的问题。

但是您可以使用以下方法在任何非特定异常上以 HTTP 500 状态返回响应:

class MyFirstAPI:
    def on_post(self, req, res):
        try:
            json_data = json.loads(req.stream.read().decode('utf8'))
            # some task
            res.status = falcon.HTTP_200
            res.body = json.dumps({'status': 1, 'message': "success"})

        except Exception as e:
            res.status = falcon.HTTP_500
            res.body = json.dumps({'status': 0,
                               'message': 'Something went wrong, Please try again'
                               })
app = falcon.API()
app.add_route("/my-api/", MyFirstAPI())

或者您也可以在 python 中使用装饰器,如下所示:

def my_500_error_decorator(func):
    def wrapper(*args):
        try:
            func(*args)
        except Exception as e:
            resp.status = falcon.HTTP_500
            resp.body = json.dumps({'status': 0, 'message': 'Server Error'})

return wrapper

class MyFirstAPI:
    @my_500_error_decorator
    def on_post(self, req, res):
        try:
            json_data = json.loads(req.stream.read().decode('utf8'))
            # some task
            res.status = falcon.HTTP_200
            res.body = json.dumps({'status': 1, 'message': "success"})
app = falcon.API()
app.add_route("/my-api/", MyFirstAPI())
于 2017-03-05T17:25:03.343 回答