当我期望 500 时,Flask 返回 200 代码

Posted

技术标签:

【中文标题】当我期望 500 时,Flask 返回 200 代码【英文标题】:Flask returning a 200 code when I expect a 500 【发布时间】:2016-02-08 15:39:55 【问题描述】:

我有一个 Flask API,它是客户服务 API 的包装器。我始终使用生成器来保持较低的内存开销。前几天我注意到第 3 方从他们的 API 中删除了一个密钥,这导致 call_cs_api 抛出异常。我预计 Flask 会因此引发 500 错误,但它会返回 200。因此,我更改了生成器以处理异常,如下所示(解决方案来自 here)。

但是,即使添加了这个,并且 werkzeug 承认了 500 错误,当我 curl 那个端点时,我仍然收到 200 返回给我。

奇怪的是,如果我打开 app.run() 并从 main 而不是通过 uwsgi 运行程序,则成功返回 500 is。所以也许这是我不知道的烧瓶设置。这是代码和一些日志跟踪:

首先,处理从第三方登录/检索数据的类:

def call_cs_api(self):
    req = requests.get(self.url)
    resp = json.loads(req.text)
    for case in resp['_embedded']['entries']:
            case = self.cleanse_data(case)
            yield (case, None)
    if next_call:
        print next_call
        try:
            print req.headers['Rate-Limit-Remaining']
            print req.headers['Rate-Limit-Reset']
            if req.headers['Rate-Limit-Remaining'] == 0:
                sleep(int(req.headers['X-Rate-Limit-Reset'])+2)
        except KeyError, e:
            yield (None, e)
        self.url = next_call['href']
        for call in self.call_cs_api():
            yield call

还有我的 Flask api:

from flask import Flask, abort, Response
import cs_api

@application.route('/users', methods = ['GET'])
def users():
    api = cs_api.CSApi('users')
    def generate():
        cases = api.call_cs_api()
        for case,e in cases:
            if case:
                yield json.dumps(case)
            if e:
                abort(500)
    return Response(generate())

@application.errorhandler(500)
    def internal_error(error):
    return "500 error - Internal Server Exception"

堆栈跟踪。最后 2 行显示 500/200 不一致:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/wsgi.py", line 682, in __next__
    return self._next()
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/wrappers.py", line 81, in _iter_encoded
      for item in iterable:
  File "cs_handler.py", line 31, in generate
      abort(500)
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/exceptions.py", line 576, in __call__
      raise self.mapping[code](*args, **kwargs)
  werkzeug.exceptions.InternalServerError: 500: Internal Server Error
  [pid: 20937|app: 0|req: 1/1] 10.100.100.51 () 38 vars in 463 bytes [Sat Nov  7 15:25:37 2015] GET /users => generated 53529 bytes in 481 msecs (HTTP/1.1 200) 1 headers in 59 bytes (50 switches on core 0)

【问题讨论】:

【参考方案1】:

errorhandler 就像一个普通的视图函数一样工作。如果不设置响应码,默认为200

返回500错误码作为第二个参数。

@application.errorhandler(500)
def internal_error(error):
    return "500 error - Internal Server Exception", 500

【讨论】:

我尝试实现这一点,但奇怪的是它仍然无法为我返回 500。我添加了一些额外的打印语句,似乎代码永远不会到达errorhandler。我还尝试过的一件事是添加stream_with_context,但这也不起作用。我有点认为对生成器的初始调用会获得 200 并始终保持该状态,但我不确定这是否正确

以上是关于当我期望 500 时,Flask 返回 200 代码的主要内容,如果未能解决你的问题,请参考以下文章

API Gateway - 来自 Postman 的 200 响应,来自应用的 500

在Flask中嵌入散景图

当我将网站上传到生产环境时,如何修复错误 500

如果 REST API 方法失败,我应该返回 200、400 还是 500 HTTP 状态消息?

遇到致命异常时如何让 php 返回 500?

当我期望一个匹配时,match() 返回具有两个匹配的数组