ネストされたTry / Catchブロックは悪い考えですか?


83

次のような構造があるとしましょう。

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このような入れ子ブロックは推奨されないという意見をいくつか見ましたが、具体的な理由は見つかりませんでした。

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


2
スニペットが実際にどれほど正確かわからない。しかし、例外をキャッチしたときに本当に知っている大騒ぎはありません。何でもかまいません。VB.NETがサポートするWhen句を活用することを検討してください。
ハンスパッサン2011年

回答:


86

例外を処理してコレクションの残りの処理を続行したい場合は、メソッド全体に対して1回のtry / catchを実行し、ループ内でもう1回実行するなど、適切な状況があります。

本当にそれを行う唯一の理由は、スタックをほどいてコンテキストを失うのではなく、エラーが発生したビットをスキップして続行したい場合です。エディタで複数のファイルを開くことは一例です。

とは言うものの、例外は(名前が示すように)例外的であるべきです。プログラムはそれらを処理する必要がありますが、通常の実行フローの一部としてそれらを回避するようにしてください。それらはほとんどの言語で計算コストがかかります(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

7
バックグラウンドスレッドへのログインは、内部のtry / catchを使用する場所です。メソッドが何をしていたかを文書化できなかったので、メソッドを終了させたくありません。
グーチ2011年

@Gooch true、私もそうします。答えに追加します。
基本的な

37

ネストされたTry/Catchブロックには本質的に何も問題はないと思いますが、ナビゲートが難しく、リファクタリング(たとえば、内部Try/Catch独自のメソッド)を実行できる可能性があります。

しかし、私はこのコメントに対処したいと思います:

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

特定の状況で例外を処理する方法がわからない場合は、私を信じてください。例外をキャッチしないでください。回復方法がわからないものをキャッチして、破損した状態でアプリを楽しく続行させるよりも、アプリをクラッシュさせる(つまり、ログに記録します。飲み込まないでください)方がよいでしょう。 。その時点から、動作はせいぜい予測不可能になります。


それは本当です。外側の例外をキャッチした時点で、私は続行したくありません。私は、アプリケーションを正常にシャットダウン/再起動し、「醜いクラッシュ」でユーザーに衝撃を与えないようにすることをもっと考えていました
Goro

10
@Goro:その場合、Application.UnhandledExceptionメソッドTry/Catchブロックごとではなく、アプリ全体の例外処理メカニズム(たとえば、これがWinFormsの場合は、イベントを処理する)をお勧めします。
ダン・タオ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.