0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

Pythonで実装している際に、標準のエラーやサードパーティ製ライブラリから出るエラーを独自のカスタムエラーでオーバーライドしてre-raiseする時などがあるかと思いますが、そんな時にエラーチェインする場合としない場合や、そのままraiseするのとraise eとするもので違いがあるのかなど気になったので調べてみました。

今回比較で使用したサンプルコード

try:
    with open("sample_file.txt", "r") as file:
        content = file.read()
except FileNotFoundError as e:
    raise  # パターン①: 簡易再送
    raise e  # パターン②: 元のエラーを再発生
    raise RuntimeError("ファイルが見つかりませんでした。")  # パターン③: エラー置き換え
    raise RuntimeError("ファイルが見つかりませんでした。") from e  # パターン④: エラーチェイン付きでエラーを発生
    raise RuntimeError("ファイルが見つかりませんでした。") from None # パターン⑤: 元の例外情報を明示的にチェインしないようにエラー置き換え

パターン①: raise

概要: exceptブロック内でraiseを呼び出すと、キャッチされた元の例外をそのまま再発生させます。

Traceback (most recent call last):
  File "main.py", line 3, in <module>
    with open("sample_file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'sample_file.txt'

特徴:

  • 元の例外を再発生させることで、最初のエラーのコンテキストが維持されるます。
  • 最もシンプルな再送方法。

パターン②: raise e

概要: 捕捉したエラーオブジェクトeを明示的に再発生させます。

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    raise e
  File "main.py", line 3, in <module>
    with open("sample_file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'sample_file.txt'

特徴:

  • スタックトレースにraise eの行番号が追加され、元のエラー発生箇所に加えて再発生箇所も表示されます。
  • raise単独のほうが基本的に適切みたい。

パターン③: raise RuntimeError(...)

概要: 元の例外を無視して新しい例外を発生させます。

Traceback (most recent call last):
  File "main.py", line 3, in <module>
    with open("sample_file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'sample_file.txt'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    raise RuntimeError("ファイルが見つかりませんでした。")
RuntimeError: ファイルが見つかりませんでした。

特徴:

  • スタックトレースには元のエラーが表示されますが、「何が原因か」の説明がないため、慎重に使用すべき。

パターン④: raise RuntimeError(...) from e

概要: 新しい例外を発生させる際に、元の例外情報をチェイン(原因として関連付け)します。

Traceback (most recent call last):
  File "main.py", line 3, in <module>
    with open("sample_file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'sample_file.txt'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    raise RuntimeError("ファイルが見つかりませんでした。") from e
RuntimeError: ファイルが見つかりませんでした。

特徴:

  • 元のエラー情報を保持しつつ、新しい例外を追加します。
  • エラーの発生原因を追いやすく、デバッグに有用。
  • Pythonicな方法として推奨される。

パターン⑤: raise RuntimeError(...) from None

概要: 新しい例外を発生させる際に、元の例外情報を明示的にチェインしないよう指定します。

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    raise RuntimeError("ファイルが見つかりませんでした。") from None
RuntimeError: ファイルが見つかりませんでした

特徴:

  • 元のエラー情報(スタックトレース)は完全に省略され、新しい例外のみが表示されます。
  • 元のエラー情報を不要として意図的に隠す場合に使用します。
  • 原因追跡が難しくなるため、使用には注意が必要です。

最後に

この記事では、Pythonで例外を再送 (re-raise) する方法について、さまざまなパターンまとめてみました。
ご拝読ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?