現在、ラッパークラスを作成しています。例外を適切にログに記録できるようにしたいのですが、呼び出し元のメソッドが発生する例外を認識できるようにします。私のクラスは次のようになります。
import logging
log = logging.getLogger('module')
class MyAPIWrapper(library.APIClass):
def __init__(self):
self.log = logging.getLogger('module.myapiwrapper')
def my_wrapper_method(self):
try:
response = self.call_api_method()
return response.someData
except APIException, e:
self.log.exception('Oh noes!')
raise e #Throw exception again so calling code knows it happened
ログに記録してから再度発生させて、呼び出し元のコードが何かを実行できるようにするためだけに、キャッチと例外について少し疑わしいです。ここでの適切なパターンは何ですか?
ログをキャッチすることに何の問題もありません。ただし、次のことをお勧めします。
try:
response = self.call_api_method()
except APIException, e: # or 'as e' depending on your Python version
self.log.exception('Oh noes!')
raise #Throw exception again so calling code knows it happened
else:
return response.someData
裸のraise
を実行するだけで、完全なトレースバック情報を保持できます。また、else
句に例外がない場合にのみ発生するコードを配置する方が明確であり、例外をキャッチしている行が明確になります。
とにかくエラーを処理している場合は、呼び出し元のクラスがロギングを行うことも問題ありませんが、それはアプリにとって便利ではない可能性があります。
編集:try ... except ... else ... finally
のドキュメントは 複合ステートメント の下にあります。
この方法は正しいですが、raise e
の代わりにraise
を使用する必要があります。これにより、最後の例外が自動的に再発生します。これは、ブランケットexcept
の使用が許容できると見なされるまれなケースの1つでもあります。
これは、Python docs on Handling Exceptions :から行っていることと非常によく似た例です。
最後のexcept句では、ワイルドカードとして機能するために、例外名を省略できます。この方法で実際のプログラミングエラーをマスクするのは簡単なので、これは細心の注意を払って使用してください。また、エラーメッセージを出力してから、例外を再発生させるためにも使用できます(呼び出し元が例外を処理できるようにします)。
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as (errno, strerror):
print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
print "Could not convert data to an integer."
except:
print "Unexpected error:", sys.exc_info()[0]
raise