2017-11-14 8 views
1

私はこれが重複している知っているが、こっちanwserは単に私を満たしていない:関数の入力が無効な場合、未定義またはエラーをスローしますか?

JS library best practice: Return undefined or throw error on bad function input?

私が指摘して何が私には不明であったいくつかのことについてお話したいと思います。

最初に、私が個人的にエラーを投げてからundefinedを返す例を示したいと思います。

function sum(a, b) 

入力ボックスの直接値を渡し、エンドユーザーが数字以外の文字を入力したため、コンシューマが文字列を渡すとします。

私がsumの著者として、文字列入力時に未定義を返した場合、デベロッパーがある時点で文字列を入力したとしても、何も起こりませんでした。しかし、この場合、私はエラーを投げてしまったのですが、デベロッパーは実際に処理しなければならなかった事実を認識していました。

だから、基本的に、devsは実際にエラーを投げてエッジケースを認識させるのはなぜですか?

これはかなりどの上記の質問にコメントした私が求めています正確に何ですが、誰もまだ返信:

「しかし、それは1余分な分を要するため、私はエラーを投げる代わりにするために暗黙のうちに死んでしまうと、ドキュメントを読む時間を取らなかった人たちの時間をデバッグするのに時間を節約できないでしょうか?」

上から受け入れanwserにあるもう一つのポイント:

は、「例外をキャッチすると、エラーがよく発生であれば、例外はなりますので、戻り値をテストするよりも多くの遅いですたくさんの遅い。

このqouteがどこに当てはまるかは、入力が常に正しい形式、例えば、ユーザーはそのIDで存在しません。

このような場合、私はエラーを投げるとプロセスが遅くなる理由を理解しています。しかし、純粋な同期関数のみで構成される数学ライブラリはどうでしょうか?

出力を確認する代わりに入力を確認する方が賢明ではありませんか?

私の混乱は実際には私がC#の世界から来て、実際にはライブラリを使うべきだと思っているからですとにかくそれが慈悲深く働いているのではなく、意図したとおりの正確な方法。

答えて

2

OO言語の場合、それは悪い習慣であり、nullの発明者がそれをbillion dollar mistakeと呼んでも、nullを返すのが一般的だと主張します。

機能的言語は、Maybeタイプを持つことによってオブジェクト指向が存在する前でもこの問題を解決しました。

関数を作成するときには、成功または失敗を含む多少の変形を使用できますが、Scott Wlaschinはこれをrailway orientated programmingと呼びます。約束は鉄道指向プログラミングの一種です。

OOでMaybeを使用する際の問題は、union typesがないことです。 F#では、あなたのコードは次のようになります。F#で何かを照合するときは、ケースを忘れてしまった場合は、コンパイル時エラーが発生します

let x = 
    // 9/0 throws so divideBy returns None the caller of divideBy can 
    //decide what to do this this. 
    match (divideBy 9 0) with 
    | Some result -> //process result 
    | None -> //handle this case 

Noneを処理できません)。オブジェクト指向では、実行時エラーに悩まされたり、静かに失敗したりすることはありません。 null可能な型にアクセスしようとすると、コンパイラに警告が出るかもしれませんが、それはif not nullの世話をするだけで、他のものを提供する必要はありません。

JavaScriptでは、私はPromisesを使用するか結果オブジェクトを返すようアドバイスします。約束は現代のブラウザーとノードのネイティブです。ブラウザでは、失敗した約束事を処理しないとき(コンソールのエラーや、ソース内のキャッチされていない拒否でのブレーク)、コンソールであなたに叫ぶでしょう。将来は;ノードjの場合。処理されない例外の場合と同様にプロセスが停止します。

//example with promises 
const processNumber = compose([ 
    //assuming divideBy returns a promise that is rejected when dividing by zero 
    divideBy(9) 
    ,plus(1) 
    ,minus(2) 
    ,toString 
]) 
// 9/0 returns rejected promise so plus,minus and toString are never executed 
processNumber(0) 
.then(
    success => //do something with the success value 
    ,fail => //do something with the failure 
); 

//example of result type: 
const Success = {} 
,Failure = {} 
,result = (type) => (value) => 
    (type === Failure) 
    //Failure type should throw when trying to get a value out of it 
    ? Object.create({type:type,error:value}, { 
     value: { 
     configurable: false, 
     get: function() { 
      throw "Cannot get value from Failure type" 
     } 
     } 
    }) 
    : ({ 
     type:type 
     ,value:value  
    }) 
; 
//convert a function (T->T) to (result T->result T) 
const lift = fn => arg => { 
    //do not call funcion if argument is of type Failure 
    if(arg.type === Failure){ 
    return arg; 
    } 
    try { 
    const r = fn(arg.value); 
    //return a success result 
    return result(Success)(r); 
    } catch (e) { 
    //return a failure result 
    return result(Failure)(e); 
    } 
}; 
//takes a result and returns a result 
const processNumber = compose(
    [ 
    //assuming divideBy throws error when dividing by zero 
    divideBy(9) 
    ,plus(1) 
    ,minus(2) 
    ,toString 
    ].map(//lift (T->T) to (result T -> result T) 
    x => lift(x) 
) 
); 

const r = processNumber(result(Success)(0));//returns result of type Failure 
if(r.type === Failure){ 
    //handle failure 
} else { 
    //handle r.value 
} 

あなたはnullを返すかスローしかしOOでより多くの人々はそれが物事を処理するためにnot the best wayだ実現するために開始することができます。スローイングは副作用であるため、関数を不純にします(より不純な関数ほど、コードを維持するのが難しくなります)。

Nullは、失敗する可能性のある関数を反映するための適切な型ではありません。なぜ期待された型を返さなかったのかわからないので、なぜコードが仮定されているのかを前提にしてコードを保守しにくくする必要があります。

+0

約束事が真剣に数学の機能などのように過度になるところはどうですか?また、C#のmaybesは素晴らしく見えます。私は彼らがキャッチすることを願っています – ThatBrianDude

+0

@ ThatBrianDude Javaでは、C#は何かが間違っていたことを示すのに使用でき、何が間違っていたのかを示すことです。私は、JavaScriptで同期関数の 'Result'型を返すほうがよいと思います。' Maybe 'のようですが、 'Some'と' None'の代わりに 'Success'と' Failure'を持ちます。ここで 'Success'は実際の値です'Failure'はエラーです。 jsのサンプルはhttps://github.com/amsterdamharu/lib/blob/master/src/index.js#L36-L125で作業していますが、明日またはそれ以降に終了する必要があります。 – HMR

関連する問題