3

私のソフトウェアは Try Catch を使用してエラーを検出します。最近エラーが発生し (データベースへのタイムアウト接続)、ユーザーに問題を警告する Messagebox.Show() がポップアップ表示されます。この社内ソフトウェアのエンド ユーザーは、IT に関する知識がまったくありません。このメッセージを受け取った女性は、誰とのつながりを失ったのかと私に尋ねました(彼女はヒッピーのように見えるので、それは精神的な「つながり」だと思っていたと思います)。

だから私がやりたいのは、エラーメッセージを単純化することです。

私が検討したこと:

ex.Message 文字列を、対応したい文字列のリストとチェック/比較できます。一致する場合は、簡略化されたバージョンを表示します。IMO、現実的ではありません。

次に、複数のキャッチがあり、特定のタイプの場合は単純なメッセージを表示することを考えました。しかし、私のコードはどれほど厄介なものになるでしょう! それだけでなく、すべての (たとえば) TimeOutExceptions が同じであるとは限らないため、誤解を招くメッセージが表示される可能性もあります。

または、これに対応するために独自の例外タイプを作成してみる必要があります。

次に、各 .NET 例外に ID が関連付けられていれば、非常に便利ですが、そのようにすれば、各 ID と自分自身の素敵で簡単に理解できるメッセージを含む適切な case ステートメントを作成できます。

他の誰かがこれを以前に検討し、適切な取り決めを見つけましたか? それとも、「エラー - 電子メールがソフトウェア ベンダーに送信されました...」というメッセージを画面に表示する方がよいでしょうか)?

4

4 に答える 4

3

Exception.message をエンド ユーザーに表示しないでください。これは、エラーの種類を識別するのに役立つ情報テキストです。

例外をキャッチするときはいつでも、それを適切に処理するか、別のものを再スロー/スローする必要があります。エラー メッセージを表示して例外を処理するコードの段階にいる場合は、例外自体から適切にコンテキストを推測できるはずです。適切な例外タイプを使用して、いくつかの基本的な例外ドメイン (DatabaseException、CommunicationException) を作成し、そのドメイン内でさらに例外を識別するエラー コードを使用できます。

Exception クラスに属し、IDictionary の型である Data プロパティを使用できるため、Exception 状態バッグとして機能します。次に、ここに 'ERR_CODE' = CONSTANT のようなものを格納し、エラー コードをチェックする例外処理の単一ポイントを設定し、エラー コードが存在する場合は、ユーザー フレンドリーな出力で例外を処理します。

現在の AppDomain 内にグローバル例外ハンドラーを登録して、キャッチされていない例外をキャッチし、メッセージを表示することもできます。これは一般的な方法ですが、このアプローチは自然なコード フローを壊すことに注意する必要があります。そのようなことが発生した場合、処理された例外は残されますが、キャッチされない例外フローが残ります (呼び出し元サイトで例外を処理しなかったため、その場合、呼び出しが失敗したことを認識せず、予期しない動作をする可能性があります)。したがって、このアプローチは、ユーザーフレンドリーなメッセージを出力してアプリケーションを終了するか、現在のユースケースを終了することによってのみ使用してください。

于 2012-10-25T08:21:04.323 に答える
2

そのようなコードを書いたことがあれば、何か間違ったcatch (Exception ex)ことをしています。例外的なコーディング状況については、常に特定の例外をキャッチする必要があります。

Eric Lippert の「厄介な例外」ブログ エントリを読んでください。

例外をキャッチしてメッセージを表示するだけは、例外の「骨の折れる」カテゴリに属します。あなたはそれらを持ってはいけません。

代わりに、Eric によって説明された他の 3 つのタイプの例外のみが必要です。また、ジェネリックException型ではなく、関連する特定の例外型をキャッチする必要があります。

特定の例外をキャッチすると、エンド ユーザーに非常に合理的なメッセージを表示できます。問題の解決方法に関する情報も提供できます。

さらに良いことに、すべての一般的な例外がコードをキャッチすることなく、デバッグが容易になり、クリーンで簡潔になります。コードのバグを予測する主な要因は、実際に記述したコード行です。コードの記述が少なくなり、バグが少なくなります。

したがって、私の提案は、コード設計を変更し、例外を適切に処理することです。

于 2012-10-25T08:23:41.393 に答える
2

catch (SomeSpecificException)一般に、例外はそのタイプ (例: )で処理する必要があります。

特定の派生例外タイプには、追加のコードがあります。

たとえばSqlExceptionNumber制御フロー/情報に使用できるプロパティがあります

catch (System.Data.SqlClient.SqlException sqlEx)
{
  if (sqlEx.Number == 1205) // Deadlock
     ...
  if (sqlEx.Number == -2) // = TimeOut
     ...
  // etc.
}

編集

実際にSystem.Exception 、保護されたHRESULT プロパティがあります。System.IO.IOException の HResult を確認する方法を参照してください。および C# で例外エラー コードを取得する方法

直接アクセスすることはできませんが、 経由で取得できますMarshal.GetHRForException(ex)。異なる例外には異なる HRESULT があります。

System.Exception :  HRESULT COR_E_EXCEPTION (0x80131500)
System.SystemException : HRESULT COR_E_SYSTEM (0x80131501)

とはいえ、他の回答によると、特定の例外をキャッチすることは、依然としてIMOの推奨されるメカニズムです-おそらくHRESULTメカニズムはCOMハングオーバーです。

于 2012-10-25T08:26:09.363 に答える
0

コードで発生する可能性があり、例外を処理できると予想される例外に対してのみ、意味のあるメッセージを処理して提供する必要があります。予期しない例外が発生した場合は、一般的なメッセージを表示し、メッセージをログ ファイルまたはイベント ログに記録します。サポートに連絡してアプリケーションを終了するようにメッセージを表示するなど、未処理/予期しない例外のポリシーをセットアップすることもできます。

于 2012-10-25T08:21:58.757 に答える