Visual Basicでは、例外処理にTry...Catch...Finallyブロックが使用されます。例外をキャッチした後に再スローするには、例外を呼び出しスタックに渡すために、演算子ThrowまたはThrow exが使用されます。
違い:
Throw(引数なし)は、現在の例外を再スローし、元の呼び出しスタック(Call Stack)を保持します。Throw exは、例外オブジェクトをスローしますが、呼び出しスタックをリセットします—問題が実際に発生した場所に関する情報を失います。例外が変更されていない場合は、引数なしのThrowを使用して正しく再スローすることをお勧めします。
正しい再スローの例:
Try DangerousOperation() Catch ex As Exception ' ロギング... Throw ' 呼び出しスタックが保持される End Try
不正な方法:
Try DangerousOperation() Catch ex As Exception Throw ex ' 呼び出しスタックがリセットされ、診断が困難になる End Try
Throw exを使用した場合、呼び出しスタックはどうなりますか?
引数なしの
Throwを使用すると、元の呼び出しスタックが保持されます—例外が発生した場所です。Throw exを使用すると、スタックは現在の行から始まり、元の発生場所が失われます。これによりデバッグが難しくなります—コードのどの部分で問題が発生したかがわからなくなります。
物語
大規模な銀行プロジェクトで、開発者はロジックエラーをスローするために
Throw exを使用しました。ログを解析すると、例外の発生場所を特定することができませんでした。適切なトレース情報が欠落していたためです。
物語
データアクセス層内でSqlExceptionをスローするために
Throwを使用していましたが、場合によっては自動コードフォーマットツールがそれをThrow exに自動的に置き換えました。これにより、ログからの自動データ抽出システムが壊れ、インシデントへの応答時間が増加しました。
物語
Exceptionオブジェクトを変更して、引数なしで
Throwを介してスローしようとしたところ、変更がログに反映されず、元のオブジェクトをInnerExceptionとして保持した新しい例外オブジェクトの明示的な作成のみが効果的でした。