当客户端尝试获取不存在的元素时,无法在 Flask 上发送 404 HTTP 状态

问题描述

在 Python/Flask 应用程序中,我定义了这个端点,如果客户端尝试获取我的数据库中不存在的 ID,我希望它返回 404。

例如:

@app.route('/plants/<int:plant_id>',methods=['GET'])
def get_plant(plant_id):
  try:
    plant = Plant.query.filter(Plant.id == plant_id).one_or_none()

    if plant is None:
      abort(404)

    return jsonify({
      'success': True,'plant': plant.format()
    })

  except:
    abort(422)

问题是当我尝试执行它时,它似乎总是引发异常并返回 422。

GET nonexistent plant on Postman returning 422

如果我删除 try/except 语法,它会按预期工作并返回 404。但我失去了处理异常的能力......所以这不是我的解决方案。

为什么我做错了?如何在不将 404 设置为异常返回的情况下正确触发 404?

谢谢!!

解决方法

好的,我终于能够理解并解决它了。我在这里发布我的发现,所以也许它可以在未来帮助某人。 :)

答案很基本,实际上:每次我中止时,我都会触发一个异常。 所以,当我中止时,无论我使用什么状态码,我都会陷入我的 except 语句中,默认返回 422。

我为解决它所做的是实现一个自定义的RequestError,并且每次我有一个受控错误时,我都会触发我的自定义错误,我可以单独控制哪个输出。

这是我自定义错误的实现:

class RequestError(Exception):
    def __init__(self,status):
        self.status = status
    def __str__(self):
        return repr(self.status)

我已经改变了我的路线实现,如下所示: (请注意,我现在首先处理自定义错误异常,然后才触发通用 422 错误)

@app.route('/plants/<int:plant_id>',methods=['GET'])
def get_plant(plant_id):
  try:
    plant = Plant.query.filter(Plant.id == plant_id).one_or_none()

    if plant is None:
      raise RequestError(404)

    return jsonify({
      'success': True,'plant': plant.format()
    })

  except RequestError as error:
    abort(error.status)

  except:
    abort(422)

就是这样! \o/