【发布时间】:2021-07-25 15:00:19
【问题描述】:
烧瓶==1.1.2 Python==3.8
我正在构建一个服务于机器学习模型的 restAPI。将向我的 restAPI 发送请求并使用结果将其发送给用户的同事希望我向他发送适当的错误消息以及 status_code。
我已经对如何正确处理 Python Flask 中的错误进行了大量搜索,但我仍然坚持对于可扩展和可维护的 restAPI 的最佳实践。
目前,每当发生错误时,我只需返回带有消息和状态代码的字典。我想缓解这种方法的一些问题:
-
如果函数内部发生错误,它必须将包含错误消息的字典返回到调用函数的位置,并需要检查它是否真的是错误,如果是则返回错误消息
例子:
def add_data(x,y): """return addition of x,y. They both need to be integers""" if type(x) != int: return "x has wrong datatype" if type(y) != int: return "y has wrong datatype" return x+y @app.route("/predict", methods=["POST"]) def predict(): data = request.get_json() result = add_data(data["x"], data["y"]) if type(result) == str: return {"message":"input error", "status":222} -
不能在函数内破坏代码。
根据一些参考资料
- Custom Python Exceptions with Error Codes and Error Messages
- What is best practice for flask error handling?
我已将代码更改为以下内容:
class InputError(Exception): status_code = 400 def __init__(self, message, status_code=None): Exception.__init__(self) self.message = message if status_code is not None: self.status_code = status_code def __str__(self): return repr(self.status_code) def add_data(x,y): if type(x) != int: raise InputError("x has wrong datatype", status_code=222) if type(y) != int: raise InputError("y has wrong datatype", status_code=222) return x+y这确实破坏了发现错误的代码,但是我无法像以前一样找出如何返回字典。
我该怎么做?哪种做法被认为是最佳做法?
【问题讨论】:
-
您将业务和传输逻辑组合在一起。
add_data不应该决定代表结果的适当 HTTP 状态代码是什么(当然也不应该决定它是 222,一个在 success 类中没有定义含义的代码) .add_data应该只是抛出一个TypeError,然后predict可以抓住它并做出适当的回应。您还应该使用isinstance进行类型比较。 -
如果我使用没有定义含义的状态码,如 1、2、3、4、5 等...?所以如果我不想将业务和传输逻辑一起破坏,我不应该输出状态码?
-
你的意思是有你自己的内部状态码,传输层转换成HTTP状态码?我想这没关系,您可以使用枚举来表示它们,因此它们是名称而不是幻数:docs.python.org/3/library/enum.html。但是,这与抛出您自己的业务相关错误有什么不同呢?