gpt4 book ai didi

python - RESTful api 设计 : handle exceptions through nested functions (python, flask)

转载 作者:太空宇宙 更新时间:2023-11-04 00:56:51 26 4
gpt4 key购买 nike

我想通过在设计 API 时更稳固地掌握 tryexceptraise 来改进我的编码风格,并且不那么冗长代码。

我有嵌套函数,当其中一个捕获到异常时,我会将异常传递给另一个,依此类推。

但像这样,我可以传播对同一错误的多次检查。我指的是:[ Using try vs if in python考虑试运行成本。

如何在嵌套函数中只处理一次错误?

例如

  • 我有一个函数 f(key) 对键进行一些操作;结果是传递给其他函数 g(), h()
  • 如果结果符合预期的数据结构,g() .. h() 将操作并返回更新结果
  • 装饰器将返回最终结果或返回第一个 遇到的错误,指出它是在哪个方法中引发的(f()g()h ()).

我正在做这样的事情:

def f(key):
try:
#do something
return {'data' : 'data_structure'}
except:
return {'error': 'there is an error'}

@application.route('/')
def api_f(key):
data = f(k)
try:
# do something on data
return jsonify(data)
except:
return jsonify({'error':'error in key'})

最佳答案

IMO try/except 是处理此用例的最佳方式。每当您想处理异常情况时,请放入 try/except。如果你不能(或不想)以某种理智的方式处理异常,让它冒泡到堆栈的更上层处理。当然,有多种理由采取不同的方法(例如,您并不真正关心错误,可以在不中断正常操作的情况下返回其他内容;您希望“异常”情况经常发生;等等),但是这里try/except 似乎最有意义:

在您的示例中,最好将 try/except 保留在 f() 之外,除非您想要……

提出一个不同的错误(小心这个,因为这会重置你的堆栈跟踪):

try:
### Do some stuff
except:
raise CustomError('Bad things')

做一些错误处理(例如日志记录;清理;等):

try:
### Do some stuff
except:
logger.exception('Bad things')
cleanup()

### Re-raise the same error
raise

否则,就让错误冒出来。

后续函数(例如 g()h())将以相同的方式运行。在你的情况下,你可能想要一些 jsonify 辅助函数,它在可能的情况下进行 jsonifies,但也处理非 json 数据:

def handle_json(data):
try:
return json.dumps(data)
except TypeError, e:
logger.exception('Could not decode json from %s: %s', data, e)

# Could also re-raise the same error
raise CustomJSONError('Bad things')

然后,您将让处理程序在堆栈的更上层处理原始错误或自定义错误,最后是一个可以处理任何错误的全局处理程序。在我的 Flask 应用程序中,我创建了自定义错误类,我的全局处理程序能够解析这些错误类并对其进行处理。当然,全局处理程序也配置为处理意外错误。

例如,我可能有一个用于所有 http 错误的基类......

### Not to be raised directly; raise sub-class instances instead
class BaseHTTPError(Exception):
def __init__(self, message=None, payload=None):
Exception.__init__(self)
if message is not None:
self.message = message
else:
self.message = self.default_message

self.payload = payload

def to_dict(self):
"""
Call this in the the error handler to serialize the
error for the json-encoded http response body.
"""
payload = dict(self.payload or ())
payload['message'] = self.message
payload['code'] = self.code
return payload

...针对各种 http 错误进行了扩展:

class NotFoundError(BaseHTTPError):
code = 404
default_message = 'Resource not found'

class BadRequestError(BaseHTTPError):
code = 400
default_message = 'Bad Request'

class NotFoundError(BaseHTTPError):
code = 500
default_message = 'Internal Server Error'

### Whatever other http errors you want

我的全局处理程序看起来像这样(我正在使用 flask_restful ,所以它被定义为我扩展的 flask_restful.Api 类中的一个方法):

class RestAPI(flask_restful.Api):
def handle_error(self, e):
code = getattr(e, 'code', 500)
message = getattr(e, 'message', 'Internal Server Error')
to_dict = getattr(e, 'to_dict', None)

if code == 500:
logger.exception(e)

if to_dict:
data = to_dict()
else:
data = {'code': code, 'message': message}

return self.make_response(data, code)

使用flask_restful,你也可以只define your error classes并将它们作为字典传递给 flask_restful.Api 构造函数,但我更喜欢定义我自己的可以动态添加有效负载数据的处理程序的灵 active 。 flask_restful 自动将任何未处理的错误传递给 handle_error。因此,这是我唯一需要将错误转换为 json 数据的地方,因为这是 flask_restful 向客户端返回 https 状态和有效负载所需要的。请注意,即使错误类型未知(例如 to_dict 未定义),我也可以向客户端返回正常的 http 状态和负载,而不必将错误转换到堆栈的下方。

同样,在应用的其他地方将错误转换为一些有用的返回值是有原因的,但对于上述情况,try/except 效果很好。

关于python - RESTful api 设计 : handle exceptions through nested functions (python, flask),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34712556/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com