42

私はそれが悪であることを知っていますが、優れたプログラマーによって書かれたコードに飲み込まれた例外を見てきました。ですから、この悪い習慣には少なくとも1つの良い点があるのではないかと思います。

言い換えれば、それは悪いことですが、なぜ良いプログラマーがまれにそれを使用するのですか?

try
{
    //Some code
}
catch(Exception){}
4

16 に答える 16

49

自分のコードを調べたところ、ファイルへの書き込みに失敗し、イベント ログへの書き込みに失敗した後、エラーを報告する場所が残っていないため、ログ コードにエラーを飲み込んでいる場所が見つかりました。これは一例です。他にはあまりありません。

于 2010-07-26T13:49:56.207 に答える
26

プログラマーがコンパイラーよりも多くの知識を持っている場合があるからです。

例 (ゼロによる除算がエラーと見なされる架空の言語で):

try {
    x = 1 / (a*a + 1);
} catch (DivisionByZeroException ex) {
  // Cannot happen as a*a+1 is always positive
}

一部の言語 (Java など) では、一部/多数/すべての例外をキャッチする必要があるため、プログラマーがそれが不可能であることを知っていても、コンパイラーはエラーを出すことがあります。コンパイラをシャットダウンさせる唯一の方法は、明示的に例外を飲み込むことです。

コンパイラが文句を言わない言語では、空のキャッチは通常まったく書かれていません。

編集:実際には、キャッチ ブロックに assert(false) を追加します。理論的に何かが起こらない場合、実際に起こると非常に深刻な問題になります;)

Edit2: Java は、チェックされた例外をキャッチすることのみを必要とします。私の発言を少し言い換えました。

于 2010-07-26T14:16:02.677 に答える
21

優れたプログラマーは、説明せずにそれを行うことはないと私は主張します。

try
{
    //Some code
}
catch(Exception e) {
    // Explanation of why the exception is being swallowed.
}

Exceptionただし、何らかの理由で、基本クラスを黙って飲み込む可能性はほとんどありません。少なくともエラーをログに記録しようとします。


今日、私のプロジェクトでたまたま出くわした具体的な例を次に示します。これはXMLHttpRequest、ブラウザでサポートされる JavaScript 関数の一部です。

var XMLHttp = null;

if( window.XMLHttpRequest ) {
    try {
        XMLHttp = new XMLHttpRequest();
    } catch(e) {} // we've already checked that this is safe. 
}
else if( window.ActiveXObject ) {
...
}

tryは、作成するオブジェクトの型をチェックする にラップされているためif...else if、例外を飲み込んでも安全です。

于 2010-07-26T13:51:26.283 に答える
16

例外を飲み込んだのは2種類しか考えられません。

  1. ファイルまたはデータベース接続を閉じるとき。終了時にエラーが発生した場合、どうすればよいですか?本当になんらかのエラーメッセージを書き出すべきだと思いますが、すでにデータを正常に読み取っていれば、余計な感じがします。また、発生するイベントとは非常に異なるようです。

  2. より正当化:内部エラー処理。ログファイルへの書き込みに失敗した場合、エラーを書き込めなかったことを示すエラーをどこに書きますか?状況によっては、画面に書き込もうとすることもできますが、アプリによっては、画面のないバックグラウンドジョブなど、それが不可能な場合があります。または、とにかくエラーについて何もできないユーザーを混乱させるだけです。

別のポスターは、例外が不可能であることがわかっている場合、または少なくとも、例外が発生するためには、2つの数値が正しく加算されなかったなど、コンパイラまたは動作環境に大きな問題が発生する必要があると述べています。例外は意味がありますか?

私は、それが正当であるこれらのまれなケースでは、例外が無関係または不可能である理由を説明するコメントを含める必要があることに心から同意します。しかし、それなら、潜在的に不可解なコードを書くときはいつでも、説明的なコメントを含めるべきだと思います。

補足:プログラマーが「x = x + 1; // xに1を追加する」のようなコメントを日常的に含めるのはなぜですか?コメントなしでは理解できませんでしたが、コメントなしで本当に不可解なコードをスローします説明?

元の投稿から4年後の補遺

もちろん、優れたプログラマーでさえ例外を飲み込むことがある本当の理由は次のとおりです。「基本的なロジックを機能させようとしています。この例外が発生した場合の対処方法がわかりません。今はそれを台無しにしたくありません。 、通常のロジックフローに問題がありますが、後で戻ります。」そして、彼らはそれに戻ることを忘れます。

ところで、私が一般的にかなり優れたプログラマーだと思う何人かの人々から聞いた悪い理由は、「ユーザーに不可解なエラーメッセージを表示したくない。それは彼らを混乱させるだけだ。エラーを黙って飲み込む方がよい。 「」これは悪い理由です。(a)ログファイルに何かを書き込むことができるからです。そして(b)不可解なエラーメッセージは、操作が成功しなかったときに操作が成功したという印象をユーザーに与えるよりも本当に悪いですか?これで、顧客は注文が実際には処理されていないときに処理されていると考えたり、救急車が派遣されて苦しんで叫んでいる子供を助けるために送られていると思ったりしますが、実際にはメッセージは届きませんでした。 、フォーラムへの当たり障りのない投稿は行われなかった、またはそのようなもの、

于 2010-07-26T17:11:40.770 に答える
9

優れたプログラマーでさえ、間違いを犯すことがあります。

それまたはあなたの優れたプログラマーの意見は一部と同じではありません (優れたプログラマーは、情報で何かが行われるのではなく、例外が飲み込まれた理由について何らかの理由を残していたからです)。

于 2010-07-26T13:49:13.723 に答える
7

プレゼンテーションのために何かを仕上げる必要があるため、上司は明日自発的に行い、プログラムがクラッシュしたり、厄介なエラー メッセージが表示されたりすることほど悪いことはありません。

もちろん、プレゼンテーションの後、誰もそれらの「迅速な修正」部分を改善することはありません。;-)

于 2010-07-27T07:51:19.270 に答える
6

これは、Javaのチェックされた例外が原因だと思います。人々はどこでも例外処理コードが必要だと考える傾向があるので、私は個人的に彼らを嫌います。コードの99%のIMOは、例外をスタックにスローし、処理しないようにする必要があります。作成された新しいメソッドのデフォルトの署名に「例外がスローされる」が含まれていると、必要がない限り例外を処理する必要がなくなります。

IMOでは、次の2つの場所でのみ例外処理が必要です。1。入力ストリームのクローズ、データベース接続、ファイルの削除などのリソースのクリーンアップ。2.例外をキャッチし、ログに記録するか、ユーザーに表示するスタックの最上部。

Thread.sleep()からのInterruptedExceptionの処理など、キャッチで実際に何もする必要がない場所があります。少なくとも、何も起こしたくないことを明確にするためのコメントが必要です。そこの。

于 2010-10-22T12:54:57.670 に答える
4

はい、元の例外をマスクしないように、例外クリーンアップ コードで頻繁に使用します。

たとえば、catch ハンドラーが例外を再スローする前にトランザクションをロールバックして接続を閉じようとしている場合、ロールバック/クローズ自体が失敗するいくつかの理由が考えられます (元の例外)。そのため、空の catch ハンドラーを使用して try ブロックでクリーンアップをラップすることをお勧めします。これは、基本的に「クリーンアップで何か問題が発生した場合でも、報告するより大きな問題があるため、それで問題ありません」と言うことができます。

于 2010-07-26T13:53:15.250 に答える
2

私はこの古いスレッドに出くわしましたが、優れたコードが (コメントの有無にかかわらず) 単純に例外を飲み込む唯一の正当な理由が見つからないことに驚きました。

ライブラリや制御外のコードを使用してコードを記述する場合、メソッドを呼び出して、そこにあるかどうかに関係なく何らかの値を取得したり、特定の時点で許可されていない可能性のある操作を実行したりする必要がある場合がよくあります。時間。呼び出しているメソッドが、制御フローの代替手段を提供する代わりに有効な結果を返すことができない場合に例外をスローする場合、値が使用できないか、操作を実行できないというシグナルとして例外を飲み込むことを余儀なくされます。

優れたプログラマーは、例外処理を使用して制御フローを駆動することを避けるためにあらゆる努力を払いますが、エラーとしてユーザーに通知される可能性が高い実際の障害シナリオを除きます。ただし、優れたプログラマーは、効率を高めるためにライブラリとフレームワークを広く再利用し、ライブラリを書き直してより良い代替手段 (TryGetValue パターンなど) を提供することが常に選択肢であるとは限らないことも理解しています。

于 2012-01-10T19:52:31.830 に答える
2

例外を効果的に処理できない場合、アプリケーションの通常の操作に影響を与えるべきではない場合、および/または既知であるが全体的な影響がほとんどない一時的な状態を表している可能性がある場合に、これを行います。

簡単な例はロギングです。一部のログ情報がバッキング ストアに保存されないという理由だけで、アプリを爆破する必要はありません。

別の例として、次のような状況を処理する別の手段がある場合があります。

private Boolean SomeMethod() {
   Boolean isSuccessful = false;
   try {
      // call API function that throws one of several exceptions on failure.
      isSuccessful = true;
   } catch(Exception) { }

   return isSuccessful;
}

上記の例では、フォールバック ポジションがない可能性がありますが、フィルターをかけたくありません。これは、try ブロックの最後のステップとして戻り値が成功ステータスにのみ設定される SHORT メソッドでは問題ありません。

残念ながら、単純にエラー コードや偽の状態を結果として返す代わりに、例外をスローする呼び出しが多数あります。また、ドキュメントが示唆するよりも多くの例外をスローする呼び出しも見てきました。これが、キャッチを配置する理由の 1 つです。

于 2010-07-26T14:07:11.203 に答える
1

優れたプログラマーであると主張しなくても、私が時々キャッチして無視する理由を少なくとも説明できます。私が取り組んでいるものは、コンパイルするために例外を処理する必要がありますが、実際に例外を処理するのに適切な場所ではありません。たとえば、私は最近、かなりの量の XML をそのタスクの 1 つとして解析するプログラムで作業していました。実際の XML パーサーがファイルを開き、例外が生成されました。ただし、XML パーサーは、不適切なファイル選択をユーザーに知らせるダイアログを生成するのに最適な場所ではありませんでした。例外を適切な場所にスローしてそこで処理することに脇道にそれるのではなく、黙って例外をキャッチし、コメントと TODO (私の IDE が追跡してくれます) を残しました。これにより、実際に例外を処理せずにコンパイルとテストを行うことができました。すぐにTODOを処理するのを忘れてしまうことがありますが、

これが最良のプログラミング手法ではないことは承知していますし、私はプロのプログラマーではありませんが、誰かがこれをやりたがる理由の一例だと思います。

于 2010-07-26T14:12:10.697 に答える
1

失敗してもプログラムを続行したいコードがある場合に、これを行いました。たとえば、オプションのログ ファイルを開きましたが、それが機能しなかった理由に関係なく、プログラムの実行を続行したいと考えています。

それでも、メモリ不足の例外などの例外が発生する可能性があるため、無視することはまったく意味がないため、良いコードではありません。公衆。(おっとっと...)

コンパイラをシャットダウンするためだけにデータまたは何かを変換するために一度実行することを目的としたプログラムでそれを行いました。ただし、これは、あらゆる形式の本番コードとはまったく異なる状況です。

基本的に、怠惰以外にこれを行う正当な理由はありません。

于 2010-07-26T14:58:04.123 に答える
0

少なくとも出力ウィンドウに書き込んでください

try
{ }
catch (exception ex)
{
System.Diagnostics.Debug.Writeline(" exception in method so and so : " ex.message);
}
于 2010-07-26T14:23:04.667 に答える
0

進行状況制御の更新を実行する場合はどうですか?コントロールの描画ルーチンで使用される状態変数を更新したので、次にコントロールが描画されるときに、適切な状態が表示されます。次に、以下を実行します。

  試す
    MyControl.BeginInvoke(MyControlUpdateDelegate);
  Exを例外としてキャッチ
  終了試行

コントロールがまだ存在する場合は、更新されます。処分されても更新されるかどうかは気になりません。コントロールが破棄されていないが、他の理由で更新できない場合でも、とにかくそれについて賢明なことは何もできないので、更新されるかどうかは気にしません。

「IfNotMyControl.IsDisposedThen ...」を追加することもできますが、それは一般的なケースに作業を追加するだけであり、BeginInvoke中にコントロールが破棄された場合に例外が発生するのを防ぐことはできません。

于 2010-07-26T15:21:24.670 に答える
0

私が作成するアプリケーションの性質上、キャッチしたほぼすべての例外をファイルに記録する必要があります。

例外は、再スロー、ログ、または例外が黙って食べられた理由を説明するコメントなしで食べられるべきではありません。初期の頃は、コードに取り組んでいるのは自分だけだとわかっていれば、例外を食べることがよくありました。もちろん、コードを再検討するときが来ると、その例外が実際に何を意味するのかを忘れてしまい、それを理解するためにすべてを再テストする必要がありました。

于 2010-07-26T15:32:15.993 に答える