1. ホーム
  2. .net

[解決済み] Try/Catchブロックのネストは悪い考えか?

2023-03-29 09:22:51

質問

例えば、次のような構造があるとします。

Try
  ' Outer try code, that can fail with more generic conditions, 
  ' that I know less about and might not be able to handle

  Try
    ' Inner try code, that can fail with more specific conditions,
    ' that I probably know more about, and are likely to handle appropriately
  Catch innerEx as Exception
    ' Handle the inner exception
  End Try

Catch outerEx as Exception
  ' Handle outer exception
End Try

という意見を見かけました。 Try のようなブロックのネストは推奨されないという意見をいくつか見ましたが、具体的な理由は見つかりませんでした。

これは悪いコードですか?もしそうなら、なぜですか?

どのように解決するのですか?

例えば、メソッド全体に対して1つのtry/catch、ループ内では例外を処理してコレクションの残りの処理を継続したいので別のtry/catchを使用するのが良い状況もあります。

それを行う唯一の理由は、スタックを巻き戻してコンテキストを失う代わりに、エラーになったビットをスキップして続行したい場合です。エディターで複数のファイルを開くのはその一例です。

とはいえ、例外は(その名が示すように)例外であるべきです。プログラムは例外を処理すべきですが、通常の実行フローの一部として例外を回避しようとします。例外処理には計算が必要で ほとんどの場合 言語(Pythonは1つの顕著な例外です)では、計算コストがかかります。

もう1つの有用なテクニックは、特定の例外タイプをキャッチすることです...

Try
    'Some code to read from a file

Catch ex as IOException
    'Handle file access issues (possibly silently depending on usage)
Catch ex as Exception
    ' Handle all other exceptions.
    ' If you've got a handler further up, just omit this Catch and let the 
    ' exception propagate
    Throw
End Try

また、エラー処理ルーチンでは、ネストされたtry/catchを使用しています...

    Try
        Dim Message = String.Format("...", )
        Try
            'Log to database
        Catch ex As Exception
            'Do nothing
        End Try

        Try
            'Log to file
        Catch ex As Exception
            'Do nothing
        End Try
    Catch ex As Exception
        'Give up and go home
    End Try