关于Pyramid视图异常处理的建议

2 投票
1 回答
1431 浏览
提问于 2025-04-18 02:18

我需要处理异常的情况有三种。

第一种是当数据验证出错时会引发异常。

第二种是当库或模块的函数出错时,比如数据库连接中断。

第三种是当业务逻辑出错时,比如出现500、503、401、403和404这些错误代码。

def library_func():
    try:
        ...
    except HTTPException:
        raise TwitterServiceException("Twitter is down!")

@view_config(route_name="home", renderer="json")
@validator
@authorization
def home_view(request):
        try:
            tweets = library_func()
            return {"tweets": tweets}
        except TwitterServiceException as e:
            LOG.critical(e.msg)
            raise ParnterServcieError(e.msg)  # this is probably a 503 error

def validator(args):
    # I will show the high level of this decorator
    try:
         decode input as JSON
         verify data format
    except ValueError as err:
        error = {'error': "Missing required parameters."}
    except json.JSONDecodeError as err:
        error = {'error': "Failed to decode the incoming JSON payload."}
    if error is not None:
        return HTTPBadRequest(body=json.dumps(error),
                              content_type='application/json')

def authorization(args):
    # very similar to validator except it performs authorization and if failed
    # 401 is raised with some helpful message.

文档建议使用自定义异常视图。在我上面的示例中,我会把ParnterServcieError作为一个例子。我甚至可以把HTTPBadRequest和所有的pyramid.httpexceptions用自定义异常来处理,这样我就不需要重复使用json.dumpscontent_type了。我可以在返回request.response对象之前设置一个通用的error内容。

我的想法是:

@view_config(context=ParnterServcieError)
def 503_service_error_view(e, request):
    request.response.status = 503
    request.response.json_body = {"error": e.msg}
    return request.response

我可以为所有未捕获的、未指定的异常(这会导致500内部服务器错误)创建一个通用的处理方式,叫做500_internal_server_error_view

这样做听起来合理吗?我处理高层和低层异常的方式是否合适,是否符合Python的风格?

1 个回答

0

我把这个方法应用到了ToDoPyramid上,成功把错误处理封装成了一个自定义的异常视图,这样之前在应用中重复出现的错误处理就只需要用这个视图就可以了。等你能进一步改进的时候,你会发现这个主意真不错。Pyramid真棒。

参考资料

撰写回答