9

例外をどこでキャッチするのが好きですか、そしてその理由は何ですか?

いくつかの一般的なパターンが現れることを期待して、try/catchブロックを配置することが人々に役立つと思う場所を確認することに興味があります。2つの回答例をC++で投稿しますが、どの言語でも問題ありません。

回答ごとに1つの場所と理由をお願いします。ありがとう。

4

9 に答える 9

10

準備ができておらず、処理できないものは捕まえないでください。

そのため、トップレベルの例外処理を用意して、予期しない例外が発生したときに好きなようにアプリケーションを爆破し、必要な機能を取得するために必要なものだけを (発生している可能性のある場所の近くで) キャッチします。

そして、2 つのことのうちの 1 つだけを行う必要があります。実際に問題を解決/回避するために何かを行うか、キャッチされた例外を として持つより説明的な例外を再スローしますinnerException

編集: ブロックが必要でfinally(たとえば、コードで割り当てたものを解放するため)、ポップアップする可能性のある例外を処理するのに役立つものが何もない場合、同じロジックが適用されます: 単にそれらを処理しないでください。代わりに、 acatch { throw; }を使用して、すべての例外情報をそのまま維持しながら、例外をより高いレベルに再スローします。(または、単純に catch ブロックを省略します。同じことをすると思いますか?)

于 2009-01-12T09:27:14.280 に答える
5

私は、対処できる例外のみをキャッチしようとしています。

私はこのようなコードが嫌いです:

      String s="12";
      Integer i;
        try {
          i = Integer.parseInt(s);
        } catch(ParseException pe) {
          System.out.println("hihihihihihihi!!!);
        }

私が特に嫌うのは、これが通常行うことは、とにかくスレッドを中止することです。なぜなら、3行後に、i!=nullと見なされるiへのアクセスがあるからです。

次に、スタックトレースを読み取り、ログをスクロールしてスクロールし、他のすべてを崩壊させた最初の重大な間違いを見つけるまでスクロールします。

とにかく、Javaが私に対処できない例外をキャッチするように強制しないことを望みます。しかし、私にできることはこれです:

catch(Exception e) {
  throw new RuntimeException(e);
}

そして、関数定義で多くの「スロー」を宣言します。

私はまだ、Eclipseがキャッチされない例外を取得したときに、正しい行でデバッガーを自動的に開く日を夢見ています。その日、私のメソッドは正しい行を開きます。

Smalltalkのような他の言語では、処理できるエラーのみをキャッチします。そして、入力が私の期待を満たさない場合、私は喜んでキャッチされない例外をスローします。

アイデアは、エラーをログに記録したり文書化したりしたくないということです。直して欲しい。

于 2009-01-12T09:04:49.143 に答える
3

私は常に最後の手段のキャッチとしてmain()にキャッチを入れます:

int main( int argc, char** argv ) {
    try {
        Application application( argc, argv );
        return application.result();
    }
    catch ( const std::exception& exception ) {
        fprintf( stderr, "%s.\n", exception.what() );
    }
}
于 2009-01-12T08:54:38.837 に答える
2

C#とJavaでは、例外をまったくキャッチしないことを好みます。それを避けられない場合は、RunTime例外をすぐに再スローします。

私は常に、必要な最大のスコープを持つ最も貪欲なcatchブロックを使用しますが、常に可能な限り最も具体的な例外タイプを使用します。catchブロックの結果は99.99%のケースで別のスローになるため、完全なメソッドをtryブロック内に保持しようとします。

于 2009-01-12T08:59:57.813 に答える
1

私は自分の例外処理コードを他のコードから分離しておくのが好きなので、通常は実際のロジックを実行するヘルパー メソッドを作成し、外側のメソッドは例外処理だけを扱います。これにより、コードがきれいになり、読みやすくなるといつも思っていました。

public void stuff() throws MyException
{
    try
    {
        tryStuff();
    }
    catch (SomeLibraryException e)
    {
        logger.log("Some message happened", e);
        throw new MyException(e);
    }
}

public void tryStuff() throws SomeLibraryException
{
   // Do things in here that could throw exceptions
}
于 2009-01-12T09:56:34.640 に答える
0

ビューから発生したイベントを処理するコントローラーのハンドラーをキャッチするのが好きです。例外が安全性の強力な保証を与える場合、これはエラーを報告するのに十分な高レベルであり、ハンドラーは通常アトミックであり、ユーザーが行ったばかりのことに関連しているため、これは有用なキャッチポイントです。どうしたの。

void Controller::on_edit_entity( const Entity& entity ) {
    try {
        Command::ptr command = new EditEntityCommand( entity );
        push_command( command );
    }
    catch ( const std::exception& exception ) {
        fprintf( stderr, "%s.\n", exception.what() );
    }
}
于 2009-01-12T08:55:26.277 に答える
0

(始める前に: 私は Java の専門家です)
私が推奨すること:

  1. 例外を適切に処理できる、例外ソースからコール チェーンの最も近いポイントを見つけます。つまり、修正措置を講じたり、トランザクション/アクションの失敗を通知したりします。ハンドラーとスローワーの間で例外を無視する必要があります。例外がこれらすべての中間メソッドに含まれないように、チェックされた例外よりもチェックされていない例外を優先します。
  2. レイヤー境界と API は、チェック済み例外を使用してスローできる例外を指定する必要があります。これらの例外の処理は、それを使用するクライアント レイヤー/コードの契約の一部であるためです。
  3. メソッドを含む例外ハンドラー クラスを作成し、handle(Exception e)最初にそれをチームにリリースし、全員がそれを使用して例外を処理するようにします。例外処理シナリオの変更に基づいて、オーバーロードされた「ハンドル」メソッドを後で追加し続けて、ハンドラーのみを変更する必要があるようにします。
  4. キャッチ アンド スローを行うときは、常に例外をチェーンすることを忘れないでください。これにより、例外の完全な原因が確実に報告されます。
  5. 同じ例外トレースを複数回ログに記録しないでください。ログファイルを使用してデバッグするのは非常に困難です。
  6. 最上位のメソッドには、システムがスローする可能性のある例外をキャッチするcatch 句が必要です。これにより、本番環境で問題が発生した場合に、内部情報が外の世界に流出するのを防ぐことができます。これはよりセキュリティ要件です。
于 2011-06-23T19:23:22.260 に答える
0

Delphi Windows アプリケーションでは、アプリケーションのメイン メッセージ処理ループ(コール スタックの一番下)がメッセージ ボックスを表示して例外を処理します。私の意見では、これは例外を処理するのに最適な場所です。

ユーザーにメッセージ ボックスを表示するという唯一の目的で独自のメソッドで例外をキャッチすることにより、例外が実際に発生し、メソッドが実際に失敗したことをメソッドを呼び出すコードが認識できなくなります。

次の場合にのみ例外を処理します。

  • クリーンアップ (DB ロールバックなど) を行う必要がある場合は、クリーンアップが完了した後に例外を再発生させます。
  • 例外に追加する情報がいくつかあります。
  • 私のメソッドは、例外にもかかわらず、その目的を達成できます。
于 2009-01-12T10:27:07.310 に答える
-1

2つの場所:

  • すべてのイベントハンドラーで
  • デバッグに役立つ情報で例外を補足するなど、catchが何か役立つことができる場所。通常、この情報を使用して新しい例外が作成され、スローされます。スタックトレースなどを保持するには、この新しい例外のInnerException(または非.NETに相当するもの)を元の例外のInnerExceptionに設定する必要があることに注意してください。
于 2009-01-12T09:03:14.560 に答える