2

我正在使用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
)

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'
4

1 回答 1

3

执行函数定义。因此,假设引发的异常特定于该装饰器,您可以将函数定义(包括装饰器)包装在 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

当然,oauth_authorized如果引发异常,这将保持未定义。在您的情况下这可能没问题,因为您可能不希望它被路由。但如果这不是你想要的,你可以在你的except块中添加一个虚拟定义。

或者,由于装饰器只是函数(嗯,任何可调用的)并且@符号只是函数调用的语法糖,您可以只将authorized_handler装饰包装在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)

如果修饰失败,这将为您留下未修饰的函数版本authorized_handler,但不会被路由。您甚至可以将上述内容放在自己的函数中并将其用作装饰器!

于 2013-06-10T21:38:01.420 回答