问题描述
在 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。
如果我删除 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/