dak ブログ

python、rubyなどのプログラミング、MySQL、サーバーの設定などの備忘録。レゴの写真も。

python での例外発生時の except と finally の実行順序

2022-09-09 12:29:20 | python
python で例外が発生した場合の except と finally の実行順序を調べてみました。
例外発生時は except を実行後に finally を実行し、except 内の raise によろ呼び出し元で例外が補足されます。
以下のプログラムで検証を行いました。

■プログラム
def func1():
    try:
        print("func1: start")
        func2()
    except Exception as e:
        print("func1: except")
        raise
    finally:
        print("func1: finally")

    print("func1: end")


def func2():
    try:
        print("func2: start")
        func3()
    except Exception as e:
        print("func2: except")
        raise
    finally:
        print("func2: finally")

    print("func2: end")

def func3():
    try:
        print("func3: start")
        raise
    except Exception as e:
        print("func3: except")
        raise
    finally:
        print("func3: finally")

    print("func3: end")

try:
    func1()
except Exception as e:
    pass

■実行結果
func1: start
func2: start
func3: start
func3: except
func3: finally
func2: except
func2: finally
func1: except
func1: finally


TypeScript での catch と finally の処理順

2022-09-09 00:24:09 | Node.js
TypeScript で例外が発生した場合に catch と finally がどのような順に実行されるかを調べてみました。
以下のプログラムでは、func1() から func2() を呼び出し、func2() からはさらに func3() を呼び出します。
func3() 内で throw した場合に、catch と finally がどのような順で呼び出されるかを確認します。

■プログラム
function func1() {
  try {
    console.log("func1: start");
    func2();
  }
  catch (e) {
    console.log("func1: catch");
  }
  finally {
    console.log("func1: finally");
  }

  console.log("func1: end");
}

function func2() {
  try {
    console.log("func2: start");
    func3();
  }
  catch (e) {
    console.log("func2: catch");
    throw e;
  }
  finally {
    console.log("func2: finally");
  }

  console.log("func2: end");
}

function func3() {
  try {
    console.log("func3: start");
    throw 'func3';
  }
  catch (e) {
    console.log("func3: catch");
    throw e;
  }
  finally {
    console.log("func3: finally");
  }

  console.log("func3: end");
}

func1();

■実行結果
func1: start
func2: start
func3: start
func3: catch
func3: finally
func2: catch
func2: finally
func1: catch
func1: finally
func1: end


実行結果をみると、finally が定義されている場合には catch が実行された後に finally が呼び出されていますが、catch 内で throw した場合には呼び出し元の処理に戻る前に finally が実行されています。