How to re-raise an exception in nested try/except blocks? Ask Question

How to re-raise an exception in nested try/except blocks? Ask Question

I know that if I want to re-raise an exception, I simple use raise without arguments in the respective except block. But given a nested expression like

try:
    something()
except SomeError as e:
    try:
        plan_B()
    except AlsoFailsError:
        raise e  # I'd like to raise the SomeError as if plan_B()
                 # didn't raise the AlsoFailsError

how can I re-raise the SomeError without breaking the stack trace? raise alone would in this case re-raise the more recent AlsoFailsError. Or how could I refactor my code to avoid this issue?

ベストアンサー1

As of Python 3, the traceback is stored in the exception, so a simple raise e will do the (mostly) right thing:

try:
    something()
except SomeError as e:
    try:
        plan_B()
    except AlsoFailsError:
        raise e  # or raise e from None - see below

SomeError生成されたトレースバックには、 の処理中に発生した追加の通知が含まれます(内にあるAlsoFailsErrorため)。これは誤解を招きやすいです。実際に発生したのはその逆で、からの回復を試みている間に に遭遇し、それを処理したからです。 を含まないトレースバックを取得するには、を に置き換えます。raise eexcept AlsoFailsErrorAlsoFailsErrorSomeErrorAlsoFailsErrorraise eraise e from None


Python 2では、例外の型、値、トレースバックをローカル変数に保存し、3引数形式のraise:

try:
    something()
except SomeError:
    t, v, tb = sys.exc_info()
    try:
        plan_B()
    except AlsoFailsError:
        raise t, v, tb

おすすめ記事