Pythonで例外が発生しそうな箇所で try
して例外をキャッチし、ログを追加するなどビジネスロジックとは別の処理をしたあとに再び同じ例外を発生させたいときがあります。
このとき、 raise e
のようにキャッチした例外をそのまま指定するコードを見かけますが、多くのケースでこれはあまり好ましくなく、何も指定しない raise
とだけ書くことが好ましいです。
raise
だけで同じ例外を発生させる事ができる
「Python文法詳解」には次のように書かれています。
except
節や、finally
節で例外ハンドラの実行中には、例外オブジェクトを指定せずにraise
文を実行できます。この場合、例外中の例外オブジェクトが、自動的に再送出されます。1
raise e
と raise
は微妙に違う
raise e
と raise
は似ている動作ですが、前者はエラーを追うときに苦労してしまいます。なぜなら、 except
内で raise e
としてしまうと、一度例外をキャッチした上で新たに例外を発生させることになってしまうのでスタックトレースのエラー箇所は raise e
と書いたところになってしまうからです。一方で raise
だけならキャッチした例外を引き継ぎ、スタックトレースを汚しません。
def test1():
try:
raise StandardError()
except Exception as e:
raise e
def test2():
try:
raise StandardError()
except Exception as e:
raise
上記の2つのコードを実行してみます。結果は次のとおりです。
>>> test1()
# Traceback (most recent call last):
# File "<input>", line 1, in <module>
# test1()
# File "<input>", line 5, in test1
# raise e
# StandardError
>>> test2()
# Traceback (most recent call last):
# File "<input>", line 1, in <module>
# test2()
# File "<input>", line 3, in test2
# raise StandardError()
# StandardError
test1()
は例外をキャッチした上で"新たに"例外 e
を発生させているため5行目でエラーになったかのように見えます。一方で test2()
は raise
で何も指定しておらず、3行目の実際のエラー箇所がスタックトレースに残っています。
-
石本敦夫 「Python文法詳解」 オライリー・ジャパン 2014年 p.184 ↩