2016-08-24 7 views
4

invalid_argument is-a logic_errorです。例外による「無効な入力」を通知する際の標準的な例外またはベストプラクティスの方法はありますか?

どちらreferencesitesはこのクラス[i.e. logic_error]は、このような論理的な前提条件やクラス不変条件の違反として、プログラムの内部論理のエラーを報告する例外としてスローオブジェクトの種類を定義する

の行に何かを示しています。

これらのエラーは、プログラムが実行される前に検出されている可能性があります。

質問:invalid_argumentのセマンティクスが厳密に「プログラマの間違い」にバインドされていることを受け入れて、があります任意のデファクトスタンダード例外プログラム/ライブラリ/サーバーが通信するために使用することができます++ランタイムで、外部の発信者に「入力が無効です」と表示されますか?
"invalid_input"タイプの例外の使用において、あなたの経験は通常のパターンを示していますか?
もしそうなら、それは標準ですか、あるいは誰もが必要に応じて例外を派生していますか?

注:はっきり

  1. stdexceptランタイムセマンティクスと何を提供していません。また、どちらも昇圧しない

  2. 私が知っている/早期の可能性のあるルールに従っている間に、入力データ(ユーザーからのものであるかどうか)を深いコンテキストでのみ検証できる十分なケースが頻繁に見つかった:可能な限り早期のものは、 "ゲートウェイで"利用可能ではない深いコンテキストとの照合を必要とするかもしれない。 (あなたがそう好む場合、またはスタック・トレースの深い)までの呼び出しチェーンで、持っている= "通信する"

    ++

// fwd declaration 
void function_facing_dirty_code(struct user_input& data); 

void function_facing_the_user(const char* jsonArgs) { 
    try { 
    struct user_input; 
    parse_user_input(json_args, user_input); 
    function_facing_dirty_code(user_input); 
    } 
    catch(invalid_input& ii) { 
    // **this** should be a standard error for erroneous input/args/etc 
    // treat it by telling the out-of-my-control caller to behave 
    } 
    catch (std::runtime_exception& e) { 
    // tell the caller: sorry, you've done nothing wrong, 
    // but I'm having generic runtime troubles. 
    } 
} 

void function_facing_dirty_code(struct user_input& data) { 
    try { 
    // ... do some work 
    // ... do some more work 
    // Ahhh 
    throw std::invalid_argument("Requested amount over the daily redraw limit"); 
    // ooops. This will cause a BSoD instead of telling the user. 
    // Because std::invalid_argument is a logic error 
    } 
    catch(std::logic_error& bsod) { 
    // log an error, blame the author, snitch it to his boss, 
    // then generate a BSoD for the user's delight, 
    // because she must NOT see our coding family's dirty laundry 
    } 
} 
+1

は、なぜ、あなたのAPIが設計されていますか?もし彼らがそれを何らかの方法で検出できるなら、そうするべきです。そうしないと、論理前提条件の違反を表す例外がスローされます。 –

+0

"これらのエラーはおそらくプログラムが実行される前に検出可能です。" 「コンパイル時にコードを記述して、これらのエラーを検出して防止する」ことを意味します。 –

+1

混乱は何ですか?引数を渡して検証し、検証に失敗した場合は、引数が無効です。誰がなぜそれが無効だと気にする?これは、無効な引数の呼び出し元の不具合なので、プログラムの論理的なエラーです。あなたが未処理の文字列を文字列に読み込んでその文字列が無効である場合、それを引数として使用する前にそれを検証しないことはあなたのせいです。すべてが合う。 – GManNickG

答えて

3
のようなブロック

std::logic_errorとその派生クラスの背後にあるアイデアは、栄光の主張のようなものです。標準ライブラリでは、それらは幾分似ています(​​- 無効なベクトルインデックスからどのような回復を望みますか?論理が壊れていることを意味し、 UBの代わりに使うことができます)。そのようなものにはinvalid_argumentが、std::bitsetにはIIRCが使用されています。

しかし、私は一般に、「無効な引数」の種類の例外が「論理」エラーまたは「ランタイム」エラーの両方から派生することに同意します。私のここでの主なポイントは、何もないところで多くの論理を求めないことです。

<stdexcept>全体は、夕食に行く前に余分な考えとして書き留められたように見え、その後完全に忘れました。極端に広いクラスのエラーは、本質的に、使用されているものの標準ライブラリでどのように使用されているかに基づいて、論理的/実行時の二分法(議論の余地のある価値) (overflow/underflow/ - 多分数学的関数について考えていたかもしれない)とキャラクタライゼーション(out_of_rangeは "論理"だが、overflow 「実行時」ですか?最高で議論の余地があります)。

簡単に言えば、stdexceptのアイデアをすぎることはありません。あまりにも漠然としていて、標準ライブラリのニーズに合うように叩かれています。あなたのアプリケーションに意味のある例外階層をstd::exceptionまたはstd::runtime_errorから派生させ、それに満足してください。人々は、彼らが事前に有効だかいないかを検出する方法はありませんで、引数に渡すように

+0

論理の誤りを見つけません - これまでの現実にマッチします。 私は何年ものJavaを使ってC++に戻ってきました。膨大な数にもかかわらず、expns階層が非常に常識的であることがわかりました。 "logic_error"と "runtime_error"を見ると、私は深刻な思考が 'stdexcept'に入ったと思っていますが、その疎さは、コードのヒープを分析し、"誰もが必要とするものです上に構築する基礎として "。サプライズ...ユーザーに "あなたの意見に間違ったことがある"と伝える人はいません - それは標準的なsoooです。それで、心配...私は何が欠けていますか? –

+0

@AdrianColomitchi: 'std :: runtime_error'は派生するように設計されています。間違っている可能性のあるカテゴリごとに、標準の例外クラスから派生した例外があるはずです。ほとんどのプログラムでほとんどのユースケースをカバーすることができる標準的な例外は存在しないため、標準的な例外の1つを実際にはほとんど排除するように設計されています。 –

+0

@MooingDuck True。しかし、標準化する価値があるほど広く使用されている例外のカテゴリがあります - 実行時のinvalid_inputはその1つです。 –

関連する問題