タグ付けされた質問 「exceptions」

例外は、プログラムの通常のフローからの逸脱を必要とするアプリケーションプロセスでの発生です。

9
多くの例外メッセージに有用な詳細が含まれていないのはなぜですか?
例外メッセージが有用な詳細を含むべきであるという合意のある量があるようです。 システムコンポーネントからの多くの一般的な例外に有用な詳細が含まれていないのはなぜですか? いくつかの例: .NETのListインデックスアクセスがArgumentOutOfRangeExceptionないではない私にしようと、無効でした指標値を教え、またそれは私の許容範囲を教えてくれありません。 基本的に、MSVC C ++標準ライブラリからのすべての例外メッセージはまったく役に立たない(上記と同じように)。 .NETのOracleの例外。「言い換えると」「テーブルまたはビューが見つかりません」と表示されますが、どちらも表示されません。 したがって、私には、ほとんどの場合、例外メッセージには有用な詳細が含まれていないようです。私の期待はずれていますか?私はこれに気付くような間違った例外を使用していますか?または、私の印象が間違っているかもしれません:例外の大部分は実際に有用な詳細を提供しますか?
220 c#  c++  exceptions 

22
null参照は本当に悪いことですか?
プログラミング言語にnull参照を含めることは「10億ドルの間違い」だと言ったと聞きました。しかし、なぜ?確かに、それらはNullReferenceExceptionsを引き起こす可能性がありますが、それではどうでしょうか?不適切に使用すると、言語の要素がエラーの原因になる可能性があります。 そして、代替手段は何ですか?私はこれを言う代わりに: Customer c = Customer.GetByLastName("Goodman"); // returns null if not found if (c != null) { Console.WriteLine(c.FirstName + " " + c.LastName + " is awesome!"); } else { Console.WriteLine("There was no customer named Goodman. How lame!"); } あなたはこれを言うことができます: if (Customer.ExistsWithLastName("Goodman")) { Customer c = Customer.GetByLastName("Goodman") // throws error …

9
制御フローとしての例外は深刻なアンチパターンと見なされますか?もしそうなら、なぜですか?
90年代後半に戻って、フロー制御として例外を使用するコードベースでかなり作業しました。テレフォニーアプリケーションを駆動する有限状態マシンを実装しました。最近、MVC Webアプリをやっているので、当時のことを思い出します。 どちらにもController、次に進む場所を決定し、データを宛先ロジックに提供するものがあります。DTMFトーンなどの旧式の電話のドメインからのユーザーアクションは、アクションメソッドのパラメーターになりましたがViewResult、aのようなものを返す代わりに、をスローしましたStateTransitionException。 主な違いは、アクションメソッドがvoid関数であったことだと思います。私はこの事実で私がしたことをすべて覚えていませんが、15年前のようにその仕事以来、私は他の仕事の生産コードでこれを見たことがないので、私は多くのことを覚える道を行くことをheしました。これはいわゆるアンチパターンであるという兆候だと思いました。 これは事実ですか?もしそうなら、なぜですか? 更新:質問をしたとき、@ MasonWheelerの回答をすでに念頭に置いていたので、私の知識に最も追加された回答を使用しました。彼も同様に正しい答えだと思います。

13
入力が技術的に有効であるが、満足できない場合の例外と空の結果セット
私は公開リリースを目的としたライブラリを開発しています。オブジェクトのセットを操作するためのさまざまなメソッドが含まれています-セットを生成、検査、パーティション分割、新しいフォームに投影します。関連する場合IEnumerableは、NuGetパッケージとしてリリースされるLINQスタイルの拡張を含むC#クラスライブラリです。 このライブラリの一部のメソッドには、満たされない入力パラメーターを指定できます。たとえば、組み合わせメソッドには、m個のアイテムのソースセットから構築できるn個のアイテムのすべてのセットを生成するメソッドがあります。たとえば、次のセットを考えます: 1、2、3、4、5 2の組み合わせを要求すると、次の結果が得られます。 1、2 1、3 1、4 等... 5、3 5、4 現在、3つのアイテムのセットを提供し、各アイテムを1回しか使用できないというオプションを設定しながら、4つのアイテムの組み合わせを要求するなど、実行できないことを要求することは明らかに可能です。 このシナリオでは、各パラメーターは個別に有効です。 ソースコレクションはnullではなく、アイテムが含まれています 要求された組み合わせのサイズは、ゼロ以外の正の整数です 要求されたモード(各アイテムを1回のみ使用)は有効な選択です ただし、パラメーターの状態を一緒にすると問題が発生します。 このシナリオでは、メソッドが例外をスローすることを期待しますか(例:)InvalidOperationException、または空のコレクションを返しますか?どちらも私にとって有効なようです: あなたは、の組み合わせを生成することができないn個のセットから項目をm個の項目N> M君はそれゆえ、一度だけ、各アイテムの使用を許可しているので、この操作は不可能と考えることができる場合InvalidOperationException。 n> mが空のセットである場合にm個のアイテムから生成できるサイズnの組み合わせのセット。組み合わせは作成できません。 空のセットの引数 私の最初の懸念は、サイズが不明なデータセットを処理する場合、例外が慣用的なLINQスタイルのメソッドのチェーンを妨げることです。言い換えれば、あなたはこのようなことをしたいと思うかもしれません: var result = someInputSet .CombinationsOf(4, CombinationsGenerationMode.Distinct) .Select(combo => /* do some operation to a combination */) .ToList(); 入力セットのサイズが可変の場合、このコードの動作は予測できません。場合は.CombinationsOf()、例外をスローしたときsomeInputSetよりも少ない4つの要素を持っている場合、このコードがします時々、いくつかの事前チェックせずに、実行時に失敗します。上記の例では、このチェックは簡単ですが、より長いLINQチェーンの途中で呼び出す場合、これは面倒になります。それが空のセットを返す場合、空になりますresult。 例外の引数 私の2番目の懸念は、空のセットを返すと問題が隠れる可能性があることです-LINQのチェーンの途中でこのメソッドを呼び出して静かに空のセットを返す場合、後でいくつかの手順で問題が発生するか、空の結果セット。入力セットに何かが確実に含まれていた場合、それがどのように発生したかは明らかではないかもしれません。 あなたは何を期待しますか、それに対するあなたの議論は何ですか?

7
適切な例外メッセージを書く方法
現在、コードレビューを行っていますが、気付いていることの1つは、例外メッセージが例外の発生場所を繰り返しているように見える例外の数です。例えば throw new Exception("BulletListControl: CreateChildControls failed."); このメッセージの3つの項目はすべて、残りの例外から解決できます。スタックトレースからクラスとメソッドを知っており、それが失敗したことを知っています(例外があるため)。 例外メッセージにどのメッセージを入れるか考えました。最初に、一般的な理由(たとえばPropertyNotFoundException- 理由)で例外クラスが存在しない場合は作成し、それをスローすると、メッセージに何が問題だったかを示します(たとえば、「ノード1234でプロパティ 'IDontExist'が見つかりません」 "- 何が)。どこにありStackTraceます。とき(該当する場合)ログに終わる可能性があります。どのように開発者がうまく(および修正)するためのものです 例外をスローするためのその他のヒントはありますか?特に、新しいタイプと例外メッセージの作成に関して。
101 exceptions 

12
例外は例外的な場合にのみ使用されるべきだと言われました。私のケースが例外的であるかどうかを知るにはどうすればよいですか?
ここでの私の具体的なケースは、ユーザーがアプリケーションに文字列を渡すことができ、アプリケーションがそれを解析し、構造化オブジェクトに割り当てることです。ユーザーが無効なものを入力する場合があります。例えば、彼らの入力は人を説明するかもしれませんが、彼らは彼らの年齢が「リンゴ」であると言うかもしれません。その場合の正しい動作は、トランザクションをロールバックし、エラーが発生したことをユーザーに伝えることであり、ユーザーは再試行する必要があります。最初のエラーだけでなく、入力で見つかったすべてのエラーについてレポートする必要があるかもしれません。 この場合、例外をスローする必要があると主張しました。彼は、「例外は例外であるべきだ。ユーザーが無効なデータを入力する可能性があるため、これは例外的なケースではない」と言って同意しませんでした。正しいようです。 しかし、そもそも例外が発明されたのはこのためだと私は理解しています。それはあなたがために使用いたエラーが発生したかどうかを確認するために、結果を検査します。チェックに失敗すると、気付かないうちに悪いことが起こる可能性があります。 例外なく、スタックのすべてのレベルが呼び出すメソッドの結果を確認する必要があり、プログラマーがこれらのレベルのいずれかをチェックインするのを忘れると、コードが誤って続行して無効なデータを保存する可能性があります(たとえば)。そのようになりやすいエラーのようです。 とにかく、ここで言ったことは何でも修正してください。私の主な質問は、例外が例外的であるべきだと誰かが言った場合、私の事例が例外的であるかどうかをどのように知ることができますか?

9
最初の処理と例外処理を確認しますか?
私は「Head First Python」という本を読んでいます(今年は私の言語です)。2つのコードテクニックについて議論するセクションに行きました: 最初のチェックと例外処理。 Pythonコードのサンプルを次に示します。 # Checking First for eachLine in open("../../data/sketch.txt"): if eachLine.find(":") != -1: (role, lineSpoken) = eachLine.split(":",1) print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals()) # Exception handling for eachLine in open("../../data/sketch.txt"): try: (role, lineSpoken) = eachLine.split(":",1) print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals()) except: pass 最初の例では、.split関数の問題を直接扱います。2つ目は、例外ハンドラーで処理できるようにします(そして問題を無視します)。 彼らは本の中で、最初にチェックする代わりに例外処理を使用するよう主張しています。引数は、例外コードがすべてのエラーをキャッチするということです。最初のチェックでは、考えていることだけをキャッチします(そして、コーナーケースを見逃します)。私は最初にチェックするように教えられたので、私の最初の本能はそれをすることでしたが、彼らのアイデアは面白いです。例外処理を使用してケースを処理することを考えたことがありませんでした。 2つのうち、どちらが一般的にベタープラクティスと見なされますか?

6
必要なメソッドパラメータにassertまたはIllegalArgumentExceptionを使用する方が良いですか?
Javaでは、どちらがより強く推奨されますか?その理由は?どちらのタイプも例外をスローするため、それらの処理に関しては同じです。assert少し短くなりますが、それがどれほど重要かはわかりません。 public void doStuff(Object obj) { assert obj != null; ... } 対 public void doStuff(Object obj) { if (obj == null) { throw new IllegalArgumentException("object was null"); } ... }

8
魔法の値を返す、例外をスローする、または失敗時にfalseを返す?
クラスライブラリのメソッドまたはプロパティを記述する必要が生じることがありますが、実際の答えがなくても失敗することは例外ではありません。何かを判断できない、利用できない、見つからない、現在不可能、または利用可能なデータがもうない。 このような比較的例外的ではない状況で、C#4の失敗を示す3つの解決策があると思います。 そうでなければ意味のないマジック値を返します(nullandなど-1)。 例外をスローします(例KeyNotFoundException)。 パラメータでfalse実際の戻り値を返し、提供しoutます(などDictionary<,>.TryGetValue)。 質問は次のとおりです。どの例外ではない状況で例外をスローする必要がありますか?そして、私が投げてはいけない場合:パラメータ付きのメソッドを実装する上で与えられた魔法の値を返すのはいつTry*outですか?(私にはoutパラメーターが汚れているようで、適切に使用するのはより手間がかかります。) 設計ガイドライン(Try*メソッドについては何も知りません)、使いやすさ(クラスライブラリを求めて)、BCLとの整合性、読みやすさなどの事実に関する答えを探しています。 .NET Framework基本クラスライブラリでは、3つのメソッドすべてが使用されます。 そうでなければ意味のないマジック値を返します。 Collection<T>.IndexOf -1を返します StreamReader.Read -1を返します Math.Sqrt NaNを返します。 Hashtable.Item nullを返します。 例外を投げる: Dictionary<,>.Item KeyNotFoundExceptionをスローします。 Double.ParseFormatExceptionをスローします。または パラメータfalseで実際の戻り値を返し、提供しoutます。 Dictionary<,>.TryGetValue、 Double.TryParse。 HashtableC#にジェネリックがなかったときに作成されたように、それが使用され、objectしたがってnullマジック値として返されることに注意してください。しかし、ジェネリックでは、で例外が使用されてDictionary<,>おり、当初はありませんでしたTryGetValue。どうやら洞察が変わります。 明らかに、Item- TryGetValueとParse-のTryParse二重性は理由があるので、非例外的な障害に対して例外をスローすることはC#4で行われていないと思います。ただし、Try*メソッドが存在した場合でも、常に存在するとは限りませんでしDictionary<,>.Itemた。

10
例外、エラーコード、差別化された組合
最近、C#プログラミングの仕事を始めましたが、Haskellにはかなりのバックグラウンドがあります。 しかし、私はC#がオブジェクト指向言語であることを理解しています。丸い釘を四角い穴に押し込みたくありません。 私は、Microsoftからの例外のスローに関する記事を読みました。 エラーコードを返さないでください。 しかし、Haskellに慣れているため、C#データ型を使用してOneOf、結果を「右」値として返すか、エラー(ほとんどの場合は列挙)を「左」値として返します。 これはEitherHaskell の慣習によく似ています。 私には、これは例外よりも安全に思えます。C#では、例外を無視してもコンパイルエラーは発生しません。例外がキャッチされない場合は、プログラムがバブルアップしてクラッシュします。これはおそらく、エラーコードを無視して未定義の動作を生成するよりも優れていますが、クライアントのソフトウェアをクラッシュさせることは、特にバックグラウンドで他の多くの重要なビジネスタスクを実行している場合、まだ良いことではありません。 を使用してOneOf、パッケージを展開し、戻り値とエラーコードを処理することを明確にする必要があります。呼び出しスタックのその段階でそれを処理する方法がわからない場合は、現在の関数の戻り値に入れる必要があるため、呼び出し元はエラーが発生する可能性があることを知っています。 しかし、これはMicrosoftが提案するアプローチではないようです。 OneOf「通常の」例外(File Not Foundなど)を処理するために例外の代わりに使用するのは合理的なアプローチですか、それともひどい習慣ですか? 制御フローとしての例外は深刻なアンチパターンと見なされていると聞いたことは注目に値します。したがって、「例外」がプログラムを終了せずに通常処理するものであれば、その「制御フロー」はある意味ではありませんか?ここに灰色の領域が少しあることを理解しています。 OneOf「メモリ不足」のようなものには使用していないことに注意してください。回復が期待できない条件でも例外がスローされます。しかし、解析されないユーザー入力は本質的に「制御フロー」であり、おそらく例外をスローすべきではないなど、かなり合理的な問題だと思います。 その後の考え: この議論から、私が現在取り上げていることは次のとおりです。 すぐに呼び出し元がcatch例外を処理し、ほとんどの場合例外を処理し、別のパスを介して作業を続行する場合は、おそらく戻り型の一部である必要があります。OptionalまたはOneOfここで役立ちます。 すぐに呼び出し元がほとんどの場合例外をキャッチしないと予想される場合は、例外をスローして、手動でスタックに渡す手間を省きます。 直近の発信者が何をしようとしているのかわからない場合は、Parseとなどの両方を提供しTryParseます。
80 c#  exceptions 

8
try ...最終的にcatch節なしで使用するのはなぜですか?
プログラムの古典的な方法はtry ... catchです。tryなしで使用するのが適切なのはいつcatchですか? Pythonでは、以下は正当であると思われ、意味をなします。 try: #do work finally: #do something unconditional ただし、コードはcatch何もしませんでした。同様に、Javaでは次のように考えることができます。 try { //for example try to get a database connection } finally { //closeConnection(connection) } 見た目が良く、突然例外の種類などを心配する必要はありません。これが良い習慣である場合、いつ良い習慣ですか?あるいは、これが良い習慣ではない、または合法でない理由は何ですか?(ソースをコンパイルしませんでした。Javaの構文エラーの可能性があるため、質問しています。Pythonが確実にコンパイルされることを確認しました。) 私が遭遇した関連する問題はこれです:私は関数/メソッドを書き続け、最後に何かを返さなければなりません。ただし、到達してはならない場所にある可能性があり、戻りポイントである必要があります。したがって、上記の例外を処理したとしてもNULL、コード内の到達すべきでないポイント(多くの場合はメソッド/関数の終わり)で、空の文字列を返すか、空のままにします。私は常にコードを再構築し、そうする必要がないようにしていますreturn NULL。なぜなら、それは絶対に良い習慣ではないように見えるからです。

14
算術オーバーフローが無視されるのはなぜですか?
お気に入りのプログラミング言語で1〜2,000,000のすべての数値を合計しようとしたことがありますか?結果は手動で簡単に計算できます。2,000,001,000,000は、符号なし32ビット整数の最大値の約900倍です。 C#が出力される-1453759936-負の値!そして、Javaも同じことをしていると思います。 つまり、デフォルトでは算術オーバーフローを無視する一般的なプログラミング言語がいくつかあります(C#には、それを変更するための非表示オプションがあります)。それは私には非常に危険に見える動作であり、Ariane 5のクラッシュはそのようなオーバーフローによって引き起こされたのではありませんか? では、このような危険な動作の背後にある設計上の決定は何ですか? 編集: この質問に対する最初の回答は、チェックの過剰なコストを表しています。短いC#プログラムを実行して、この仮定をテストしましょう。 Stopwatch watch = Stopwatch.StartNew(); checked { for (int i = 0; i < 200000; i++) { int sum = 0; for (int j = 1; j < 50000; j++) { sum += j; } } } watch.Stop(); Console.WriteLine(watch.Elapsed.TotalMilliseconds); 私のマシンでは、チェックされていないバージョンは4125msかかりますが、チェックされたバージョンは11015msかかります。つまり、チェック手順は、数値を追加するのにほぼ2倍の時間がかかります(元の時間の合計3倍)。しかし、10,000,000,000回の繰り返しで、チェックにかかる時間はまだ1ナノ秒未満です。それが重要な状況があるかもしれませんが、ほとんどのアプリケーションでは、それは重要ではありません。 編集2: サーバーアプリケーション(いくつかのセンサーから受信したデータを分析するWindowsサービス)を/p:CheckForOverflowUnderflow="false"パラメーターで再コンパイルし(通常、オーバーフローチェックをオンにします)、デバイスに展開しました。Nagiosモニタリングは、平均CPU負荷が17%に留まったことを示しています。 これは、上記の構成例で見つかったパフォーマンスヒットは、アプリケーションにとってまったく無関係であることを意味します。


12
エラーをスローすべきかどうかを示すフラグを持っている
私は最近、かなり古い開発者(50歳以上)がいる場所で働き始めました。彼らは、システムがダウンすることができなかった航空を扱う重要なアプリケーションに取り組んできました。その結果、古いプログラマーはこの方法でコーディングする傾向があります。 彼は、オブジェクトにブール値を入れて、例外をスローすべきかどうかを示す傾向があります。 例 public class AreaCalculator { AreaCalculator(bool shouldThrowExceptions) { ... } CalculateArea(int x, int y) { if(x < 0 || y < 0) { if(shouldThrowExceptions) throwException; else return 0; } } } (このプロジェクトでは、その時点では存在できないネットワークデバイスを使用しようとしているため、メソッドは失敗する可能性があります。エリアの例は、例外フラグの例にすぎません) 私にはこれはコードの匂いのようです。毎回例外フラグをテストする必要があるため、単体テストの作成は少し複雑になります。また、何か問題が発生した場合、すぐに知りたいと思いませんか?続行方法を決定するのは呼び出し側の責任ではないでしょうか? 彼の論理/推論は、プログラムがユーザーにデータを表示するという1つのことをする必要があるということです。それを妨げないその他の例外は無視する必要があります。私はそれらが無視されるべきではないことに同意しますが、バブルアップして適切な人によって処理されるべきであり、そのためのフラグを処理する必要はありません。 これは例外を処理する良い方法ですか? 編集:設計上の決定についてより多くのコンテキストを与えるために、このコンポーネントが失敗した場合でも、プログラムは引き続き動作し、メインタスクを実行できるためだと思います。したがって、例外をスローしたくない(そして、それを処理しない?)ので、ユーザーが正常に動作しているときにプログラムを停止させます 編集2:より多くのコンテキストを与えるために、この場合、メソッドはネットワークカードをリセットするために呼び出されます。ネットワークカードが切断および再接続され、異なるIPアドレスが割り当てられると問題が発生します。したがって、古いIPでハードウェアをリセットしようとするため、リセットは例外をスローします。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.