【问题标题】:Python decorator error handlingPython 装饰器错误处理
【发布时间】:2017-06-26 15:57:02
【问题描述】:

我正在创建瓶子休息 API,我想在某些端点使用函数装饰器来验证用户。装饰器代码是:

def authenticating_decorator(func):
    def wrapper():
        try:
            '''
            auth user before execution of the required code
            if user is not authenticated bottle.HTTPError is raised
            '''
            auth()  
            return func
        except HTTPError as e:
            return handle_auth_error  

    return wrapper()

return authenticating_decorator

处理认证错误函数:

def handle_auth_error(error):
    return {
        "code": error.status_code,
        "name": error.body.get('name'),
        "description": error.body.get('description')
    }

除了我安装了 Bottle 插件来捕获异常并将它们转换为所需的 JSON 并且 API 响应的内容类型为 application/json 之外,一切都运行良好

auth 方法发生异常时,API 返回已知 html 格式的错误,因为它以某种方式跳过了我的错误插件。 (同时使用插件和装饰器时,我可能并不完全了解应用程序流程)

我的错误插件的调用方法:

def __call__(self, callback):
    def wrapper(*a, **kw):
        try:
            rv = callback(*a, **kw)
            return rv
        except HTTPError as e:
            response.status = e.status_code
            return {
                "code": e.status_code,
                "name": e.body.get('name'),
                "description": e.body.get('description')
            }
    return wrapper

我的意思是我必须将函数传递给插件,因为 rv = callback(*a, **kw)

由于我在装饰器的 auth() 方法中有多种类型的异常,我想将异常作为参数传递给装饰器中的handle_auth_error

但是如果我输入 return handle_auth_error(e) 函数返回 dict,而不是函数,我得到异常 dict object is not callable at code line rv = callback(*a, **kw)

如何从装饰器返回带有参数的函数而不在装饰器中调用它但在插件中调用它? 或者如何将异常作为参数传递给插件?

可能的解决方案是使用基于异常名称的“switch”语句创建自己的函数来处理每个可能的异常,但我想以编程方式进行:

 return {
     'HEADER_MISSING': handle_header_missing_exception,
     'TOKEN_EXPIRED': handle_expired_token_exception,
      etc ... : etc...
            }.get(e.body.get('name'))

【问题讨论】:

    标签: python plugins decorator bottle


    【解决方案1】:

    我认为你的装饰器写得不正确,不应该是这样吗:

    def authenticating_decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            try:
                 '''
                auth user before execution of the required code
                if user is not authenticated bottle.HTTPError is raised
                '''
                auth()  
                return func(*args, **kw) #calling func here
            except HTTPError as e:
                return handle_auth_error(e)  #calling the handle_auto_error here
    
    return wrapper #notice - no call here, just return the wrapper
    

    【讨论】:

      猜你喜欢
      • 2013-06-08
      • 1970-01-01
      • 2018-08-11
      • 2016-09-27
      • 2021-07-11
      • 2018-01-28
      • 2010-12-19
      • 2021-12-28
      • 2021-08-19
      相关资源
      最近更新 更多