Tweepyでエラーにならないように例外処理する

PythonでTwitter APIを扱うためにTweepyを使ってみたのですが、404エラーになるようなAPIを叩いた時にエラーになっちゃう。

>>> oauth_api.retweets(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/tweepy/binder.py", line 184, in _call
    return method.execute()
  File "/tmp/tweepy/binder.py", line 167, in execute
    raise TweepError(error_msg, resp)
tweepy.error.TweepError: Not found

raiseってなんだっけ?と思ってチュートリアルを確認。
例外の話が出てきました。
ふむふむ。きっとTweepErrorってのがTweepyで定義した例外なんだろうな。
try-exceptで例外を処理してあげればいいんですね。

>>> try:
...   oauth_api.retweets(1)
... except TweepError:
...   dir(TweepError)
... 
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
NameError: name 'TweepError' is not defined

エラーが変わった。
TweepErrorなんてないよって言ってる。
ってことはimportしないといけないのか。



初めに出たエラーからするとtweepy.error.TweepErrorって書けば問題ないのかな?

>>> try:
...   oauth_api.retweets(1)
... except tweepy.error.TweepError:
...   dir(tweepy.error.TweepError)
... 
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__str__', '__weakref__', 'args', 'message']
>>> 

いけたいけた。
普通は「from tweepy.error import TweepError」とかするのかな?
とりあえずこのまま進もう。



やり方がわかったところで、Tweepyの中でTweepErrorを使ってないかgrepしてみる。
tweepy/api.pyの310行目で使ってました。

        except TweepError, e:
            if e.response and e.response.status == 401:
                return False
            raise

なるほどなるほど。こういう風 にeを使って処理すればいいのね。



試してみる。

>>> try:
...   oauth_api.retweets(1)
... except tweepy.error.TweepError, e:
...   dir(e)
... 
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__str__', '__weakref__', 'args', 'message', 'reason', 'response']

argsとmessageとreasonとresponseがあるんですね。



出力してみる。

>>> try:
...   oauth_api.retweets(1)
... except tweepy.error.TweepError, e:
...   print e.args
...   print e.message
...   print e.reason
...   print e.response
... 
()

Not found
<httplib.HTTPResponse instance at 0x423a30>

必要なのはreasonとresponseくらいか。



responseの中身を確認。

>>> try:
...   oauth_api.retweets(1)
... except tweepy.error.TweepError, e:
...   dir(e.response)
... 
['__doc__', '__init__', '__module__', '_check_close', '_method', '_read_chunked', '_read_status', '_safe_read', 'begin', 'chunk_left', 'chunked', 'close', 'debuglevel', 'fp', 'getheader', 'getheaders', 'isclosed', 'length', 'msg', 'read', 'reason', 'status', 'strict', 'version', 'will_close']

使えそうなのはmsgとreasonとstatusくらいかな?
とりあえずapi.pyの中でやってるようにstatusでコードを確認して、ヘッダとかまで確認したければmsgの中身見ればいいのかな。



ということで、最終的にこんな感じになりました。

>>> from tweepy import *
>>> consumer_token = "xxxx"
>>> consumer_secret = "xxxx"
>>> access_token = "xxxx"
>>> access_token_secret = "xxxx"
>>> auth = API(OAuthHandler(consumer_token, consumer_secret))
>>> oauth_api = auth.set_access_token(access_token, access_token_secret)
>>> 
>>> try:
...   oauth_api.retweets(1)
... except TweepError, e:
...   if e.response and e.response.status == 404:
...     print 'error'
... 
error

できたできた。