如何捕获装饰器中引发的错误?

时间:2013-06-10 21:21:14

标签: python flask decorator

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

1 个答案:

答案 0 :(得分:3)

执行函数定义。因此,假设引发的异常特定于该装饰器,您可以将函数定义(包括装饰器)包装在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装饰失败,这将为您留下未修饰的函数版本,但不会路由它。您甚至可以将上述内容放在自己的函数中,并将其用作装饰器!