web-dev-qa-db-ja.com

InvalidArgumentExceptionとUnexpectedValueException

いつ InvalidArgumentException を使用する必要があり、いつ nexpectedValueException を使用する必要がありますか?彼らは私には同じように見えます。

一方はLogicExceptionを拡張し、もう一方はRuntimeExceptionを拡張するため、違いはそれほど微妙なIMOであってはなりません。

38
ChocoDeveloper

マニュアルページの説明をよく見てください。

InvalidArgumentException

引数が予期されたタイプではないの場合に例外がスローされます。

(説明はException thrown if an argument does not match with the expected value.2014年半ばまで 、ただし変更されました PHP 5.6が導入されたとき

nexpectedValueException

値が値のセットと一致しないの場合に例外がスローされます。通常、これは、関数が別の関数を呼び出し、戻り値が特定のタイプまたは値[、]であり、算術エラーまたはバッファ関連エラーを含まないことを期待している場合に発生します。

このことから、InvalidArgumentException引数のタイプをチェック関数に渡されることを意図しているのに対し、UnexpectedValueException値と有効な値セットを検証するを意図していると結論付けることができます。関数の計算(たとえば、他の関数から返された値)。

引数の値をチェックすることは、ここでは一種の灰色の領域であることに注意してください。間違いなく、InvalidArgumentException extends LogicException、それは should lead directly to a fix in your code. 入力値が範囲外の場合に例外をスローすることは完全に予想されるため、runtimeの動作であるため、このような場合の唯一の候補としてUnexpectedValueExceptionRuntimeExceptionを拡張)が残ります。

28
outis

最大の違いは「議論」と「価値」だと思います。

私の見方では、InvalidArgumentExceptionは(渡された)引数用ですが、UnexpectedValueExceptionは(返された)に適用されます。また、「無効」と「予期しない」の間には微妙ですが重要な違いがあります。これは、最初がLogicExceptionで、2番目がRuntimeExceptionである理由も説明しています。

例:Twitter-apiを利用する関数があるとします:getLastMessageDate($userid) :(数値の)ユーザーIDを渡すと、そのユーザーの最後のメッセージの日付がyyyy-として返されます。 mm-dd文字列。

ここで、数値ではなく文字列を引数としてこの関数を呼び出すとします。提供された引数はこの関数に対して無効であるため、この時点でInvalidArgumentExceptionを呼び出すことができます。これらのチェックは、logicによって実行できます-変数は数値であるかそうでないかのどちらかであるためです。したがって、これはLogicExceptionです。

ただし、関数の戻り値は、ロジックでは検証できない場合があります。特に、(サードパーティの)動的コンテンツを扱っている場合はそうです。関数が何を返すかを正確に知ることはできないからです。 (もしそうなら、これは間違いなくあなたの関数を役に立たなくするでしょう。)

そのため、今回は(有効な)ユーザーIDを使用して関数を呼び出し、関数はそのユーザーの最後のメッセージの日付を取得します。この日付で、フォーマットなどの何かをしたいと思います。

Twitterの人たちが何か間違ったことをしたと想像してみてください。私のexpectedyyyy-mm-dd date-stringの代わりに、空の文字列または別の文字列が表示されます「blaaaa」と言っています。この時点で、UnexpectedValueExceptionをスローできます。

この値が「無効」であるとは言えません。文字列を要求したところ、文字列を取得しました。しかし、それは私が期待していた「文字列の種類」ではありません。したがって、予期しない ValueException。

これが何かをクリアすることを願っています。これは私の最初の投稿です-これまでのところ、頭の中にあるものを書き留めることは最も簡単なことではないことを学びました(英語も私の母国語ではありません)。

17
bartvanraaij

私の理解では、可能な値の範囲の固定リストに対して引数をチェックする場合は、 InvalidArgumentException であるLogicExceptionを使用する必要があります。たとえば、ユーザーが入力したデータに数字のみが含まれているかどうかを確認します。プログラムlogicは、これらの値の範囲を処理することが期待できます。

UnexpectedValueExceptionRuntimeException実行時にのみ検出できる/コンパイル時に検出できないエラー)、予測可能で指定された入力範囲外で発生する例外に使用されます(おそらく、上記の「ロジック」チェック後の最後の手段として)。

この質問に答える鍵は、UnexpectedValueExceptionUnexpected...かもしれません。 Unexpectedは、プログラムロジックでこの値を処理しないことを意味します。一方、Invalidは、この値が処理されたことを示します。

14
ax.