Pythonの例外再送出:エラーをログに残して呼び出し元に通知する方法

例外処理(try-except)を実装する際、「その場でエラーを解決する」のではなく、「エラーが発生したという事実をログに記録し、実際の対処は呼び出し元(上位の処理)に任せたい」というケースがあります。

このような場合に有効なのが、**例外の再送出(Re-raising)**です。一度捕捉した例外を、意図的に再度発生させることで、エラー情報を握りつぶさずに上位へ伝播させることができます。

この記事では、raise 文を使用した例外の再送出方法と、トレースバック(エラーの発生箇所情報)を正しく維持するための記述方法について解説します。

目次

例外の再送出とは

try-except ブロックで例外を捕捉すると、通常そのエラーはそこで「解決済み」とみなされ、プログラムは後続の処理を続行します。

しかし、関数内で発生した致命的なエラーなどは、関数内部だけで処理を完結させず、関数を呼び出した側に「エラーが起きた」ことを通知する必要があります。この時、except ブロック内で raise 文を使用します。

正しい再送出の方法:引数なしの raise

例外を再送出する場合、最も推奨される方法は、引数を指定せずに単独で raise と記述することです。

構文:

try:
    # 処理
except Exception:
    # ログ出力などの処理
    raise  # 捕捉した例外をそのまま再送出する

具体的な使用例

設定ファイルの値を読み込み、数値に変換する関数を例にします。変換に失敗した場合、エラーログを出力した上で、システム全体に異常を知らせるために例外を再送出します。

def parse_configuration(config_value):
    """
    設定値を数値に変換する関数
    """
    try:
        # 文字列を整数に変換(失敗すると ValueError)
        result = int(config_value)
        return result

    except ValueError:
        # 1. ここでエラーを検知し、ログを出力する
        print(f"[Log] 設定値の変換に失敗しました。値: {config_value}")
        
        # 2. 例外を再送出する(呼び出し元にエラーを通知)
        raise

# --- メイン処理 ---
print("処理を開始します。")

try:
    # 不正な値(文字列)を渡して関数を実行
    value = parse_configuration("InvalidNumber")
    
except ValueError:
    # 3. 呼び出し元で再送出された例外を捕捉する
    print("[System] 設定エラーのため処理を中断します。")

print("処理を終了します。")

実行結果:

処理を開始します。
[Log] 設定値の変換に失敗しました。値: InvalidNumber
[System] 設定エラーのため処理を中断します。
処理を終了します。

この流れにより、「関数内でのログ出力」と「呼び出し元でのエラー対応(中断処理)」の両方が実現されています。

raise eraise の違い

例外オブジェクトを変数で受け取り、raise e のように記述して再送出することも可能です。

    except ValueError as e:
        print("ログ出力")
        raise e  # 変数を指定して再送出

しかし、単に元の例外をそのまま上に投げるだけであれば、引数なしの raise が推奨されます。

  • raise (引数なし): 発生した例外の「トレースバック(エラーが発生した行番号などの履歴)」をそのまま維持して送出します。デバッグ時に、最初のエラー発生箇所が明確になります。
  • raise e: Pythonのバージョンや状況によっては、トレースバック情報が上書きされ、どこで最初のエラーが起きたのかが追いにくくなる場合があります(Python 3では連鎖例外として扱われますが、意図がない限り raise 単独の方がシンプルで副作用がありません)。

まとめ

  • 例外を捕捉した後、ログ出力や一時的な後始末を行い、エラー自体は上位の処理に任せたい場合に「再送出」を使用します。
  • except ブロック内で単に raise と記述することで、現在捕捉している例外をそのまま再送出できます。
  • これにより、エラーの発生箇所(トレースバック)を正確に保ったまま、エラー情報を伝播させることができます。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次