本文介绍了如何捕获装饰器中引发的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用flask-auth,它提供了一些辅助装饰器。我已经添加了下面所有的各种方法,但我想问的问题是如何捕获由 authorized_handler 装饰器抛出的任何问题。这是一个关于装饰者的普遍问题,但我认为一个真正的例子可能会有帮助。

如果装饰者爆炸了,我怎么能抓住它?

  import os 
import flask
import flask_oauth

CONSUMER_KEY = os.environ ['CONSUMER_KEY']
CONSUMER_SECRET = os.environ ['CONSUMER_SECRET']

oauth = flask_oauth.OAuth()
twitter = oauth.remote_app(
'twitter',
base_url ='https://api.twitter.com/1/',
request_token_url ='https://api.twitter.com/oauth/request_token',
access_token_url ='https:// api.twitter.com/oauth/access_token',
authorize_url ='https://api.twitter.com/oauth/authenticate',
consumer_key = CONSUMER_KEY,
consumer_secret = CONSUMER_SECRET

$ b $应用程序= flask.Flask(__ name__)

@ app.route('/ login')
def login():
返回twitter.authorize(
callback = url_for(
'oauth_authorized ,
next = request.args.get('next')或request.referrer或None)


@ app.route('/ oauth-authorized')
#如果这样会产生错误,会发生什么?
@ twitter.authorized_handler
def oauth_authorized(resp):
print'foo-bar'


解决方案

执行函数定义。因此,假设引发的异常是特定于装饰器的,那么可以将函数定义(包括装饰器)包装在 try / except 中:

 尝试:
@ app.route('/ oauth-authorized')
@ twitter.authorized_handler
def oauth_authorized(resp) :
print'foo-bar'
除了WhateverError外e:
printtwitter.authorized_handler引发错误,e

当然,如果引发异常,会导致 oauth_authorized 不确定。这可能是你的情况,因为你可能不希望它被路由。但是,如果这不是你想要的,你可以为除了块添加一个伪定义。



,因为装饰器只是函数(以及任何可调用的)而 @ 表示法只是函数调用的语法糖,所以可以只包含 authorized_handler 装饰在 try / except :

  
print'foo-bar'
try:#apply decorator
oauth_authorized = twitter.authorized_handler(oauth_authorized)
除了Exception:e
打印twitter.authorized_handler引发错误,e
else:#没有错误装饰与authorized_handler,应用app.route
oauth_authorized = app.route('/ oauth-authorized')(oauth_authorized)

如果 authorized_handler 装饰失败,但不会被路由。你甚至可以把上面的代码放在自己的函数中,并用它作为装饰器!


I am using flask-auth, which provides some helper decorators. I've added all the various methods below, but the question I want to ask is how to catch any issues thrown by the authorized_handler decorator. It's a general question about decorators, but I thought a real example might help.

If the decorator blows up, how could I catch it?

import os
import flask
import flask_oauth

CONSUMER_KEY = os.environ['CONSUMER_KEY']
CONSUMER_SECRET = os.environ['CONSUMER_SECRET']

oauth = flask_oauth.OAuth()
twitter = oauth.remote_app(
    'twitter',
    base_url='https://api.twitter.com/1/',
    request_token_url='https://api.twitter.com/oauth/request_token',
    access_token_url='https://api.twitter.com/oauth/access_token',
    authorize_url='https://api.twitter.com/oauth/authenticate',
    consumer_key=CONSUMER_KEY,
    consumer_secret=CONSUMER_SECRET
)

app = flask.Flask(__name__)

@app.route('/login')
def login():
    return twitter.authorize(
        callback=url_for(
            'oauth_authorized',
            next=request.args.get('next') or request.referrer or None)
    )

@app.route('/oauth-authorized')
# what happens if this raises an error?
@twitter.authorized_handler
def oauth_authorized(resp):
    print 'foo-bar'
解决方案

Function definitions are executed. Therefore, assuming the exception raised is specific to that decorator, you can wrap the function definition, including decorators, in a try/except:

try:
    @app.route('/oauth-authorized')
    @twitter.authorized_handler
    def oauth_authorized(resp):
        print 'foo-bar'
except WhateverError as e:
    print "twitter.authorized_handler raised an error", e

Of course, this will leave oauth_authorized undefined if the exception is raised. This is probably OK in your case since you probably don't want it to be be routed anyway. But if this isn't what you want, you could add a dummy definition to your except block.

Or, since decorators are just functions (well, any callable) and the @ notation is merely syntactic sugar for a function call, you can wrap just the authorized_handler decoration in try/except:

def oauth_authorized(resp):
    print 'foo-bar'
try:    # apply decorator
    oauth_authorized = twitter.authorized_handler(oauth_authorized)
except Exception as e:
    print "twitter.authorized_handler raised an error", e
else:   # no error decorating with authorized_handler, apply app.route
    oauth_authorized = app.route('/oauth-authorized')(oauth_authorized)

This will leave you with the undecorated version of the function if the authorized_handler decoration fails, but it will not be routed. You could even put the above in its own function and use it as a decorator!

这篇关于如何捕获装饰器中引发的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-13 13:17