2011-12-15 25 views
11

Node.jsのコールバック関数のgeneral conventionは、エラーの最初のパラメータ(存在する場合)を「予約」することです。たとえば:Node.jsコールバック経由で複数のエラーを返すための規約?

callSomeBlockingFcn(function callbackWhenDone(err, result) { 
    if(err) ... 
}); 

あなたが複数のエラーを返す必要がある場合 - 複数のデータ検証エラーが言うには、例えば - それは、エラーオブジェクトの配列を渡すために貧しいフォームを考えられていますか?例:

var callSomeBlockingFcn = function(callback) { 
    // multiple errors to report back... 
    callback([ err1, err2, ...]); 
} 

または、配列を参照し、配列を参照するプロパティ(必要に応じて)を持つ単一のオブジェクトを返すことをお勧めしますか?例:

var callSomeBlockingFcn = function(callback) { 
    // multiple errors to report back... 
    callback({ errors: [ err1, err2, ...] }); 
} 

答えて

9

3年後:コールバックの配列は私が狂ったようになります置く

誰でも。

正しい解決策は、errorを最初の引数として返すことです。複数のエラーを返す場合は、例外的でない場合にはおそらくエラーを使用しています。

この場合、コールバックの「値」スロット、つまり2番目の引数に入る必要があります。最初の引数は、予期せぬ1つの操作上のエラーです。あなたが複数の予期せぬ操作ミス(そう)をお持ちの場合

あなたはこのMultiError

オリジナルのような何かを行うことができます:

は、私はエラーの配列を返すと間違って何もないと思います。

ValidationErrorという新しいカスタムを返すことができますが、これは配列である"messages"のプロパティを持ちます。同じ問題の検索を経由して、この問題を発見

A)

function validateX(x, cb) { 
    ... 
    if (errorMessages) { 
    return cb(errorMessages); 
    } 
} 

B)

function ValidationError(msgs) { 
    this.messages = msgs; 
} 

function validateX(x, cb) { 
    ... 
    if (errorMessages) { 
    return cb(new ValidationError(errorMessages)); 
    } 
} 
+0

エラーが効果的に「エラー」であるべきであることに注意してください。 – laconbass

+1

私はあなたに「*エラーの配列を返しても何も問題はないと思う」とdownvotingしますが、100ポイントのバウンティ*もっと注意を引くために私がそれを購入したときに他の誰も答えなかったので、私はポイントを与える*誰も)*。おそらく、98ポイントの純利益は、問題を再検討して再考する小さなインセンティブになるでしょう:-P ...私は、キヤノンがエラーの配列がノードの有効なエラーパラメータではないと考えているからです。 – HostileFork

+0

@HostileForkチャレンジが受け入れられました:)答えを修正しました。 – Raynos

4

。私は周りを見回して、私はerrがエラー以外の何ものでもないと信じていないという結論に達しましたが、nullです。

http://docs.nodejitsu.com/articles/errors/what-are-the-error-conventions

のNode.jsでは、次のようにそれらを返すことで、非同期機能でエラーを処理するために標準的と考えられている:

私が見つけた最高の「権威」のソースはNodejitsuのヘルプトピックです現在の関数のコールバックへの最初の引数。エラーがある場合は、最初のパラメータにすべての詳細を含むErrorオブジェクトが渡されます。それ以外の場合、最初のパラメータはnullです。

しかし、私はあなたが直感的にそれがなぜそうであるべきかについて議論をすることができると思います。エラーがあったかどうかを判断するコードにはif (err)テストが多数ありますが、0またはfalseまたはundefinedまたはNaNまたは空の文字列を渡すべきではありません。あなたが望むなら、if (err == null)でテストできるはずです。

nullではないが、一致しないエラーフィールドに何かを戻すと、if (err instanceof Error)が厄介に見えます。だから私は配列やオブジェクトを使用しないことをお勧めします。その場合は、アレイ内のどのエラーも、集計エラーが作成された場所を特定するものではないことにも注意してください。これは、「実際のエラー」が発生したポイントです。エラーが発生したことが処理できるものではないという決定の瞬間だったからです。

しかし、これはあなたがそれを得るためにはもう少し作業が必要と思います意味:

function MultipleError (errs) { 
    // http://stackoverflow.com/a/13294728/211160 

    if (!(this instanceof MultipleError)) { 
     return new MultipleError(errs); 
    } 

    Error.call(this); 
    this.errs = errs; 

    // captureStackTrace is V8-only (so Node, Chrome) 
    // https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi 

    Error.captureStackTrace(this, MultipleError); 
}; 

MultipleError.prototype.__proto__ = Error.prototype; 
MultipleError.prototype.name = 'MultipleError'; 
MultipleError.prototype.toString = function() { 
    return 'MultipleError: [\n\t' + this.errs.join(',\n\t') + '\n]'; 
} 

ビットの行き過ぎを、多分。しかし、本当に集計を表すエラーを選ぶことができず、誰かがエラーのセットに関心を持つかもしれないと思うのであれば、それはあなたがしたいと思うだろうか?必要に応じてerrs配列を調べてください。

+0

JS Optimizationを防ぐことができる 'MultipleError.prototype .__ proto__'の代わりに(https://developer.mozilla.org/en-US/docs/Web/JavaScript/The_performance_hazards_of__%5B%5BPrototype%5D% 5D_mutation)を使用する場合は、 'MultipleError.prototype = Object.create(Error.prototype、{コンストラクタ:{値:MultipleError}、名前:{値: 'MultipleError'}、toString:{value:function(){/...}}}); '、' MultipleError'上のそれらのプロパティを設定不可能で非列挙可能にするという追加のボーナスがあります。 – snickle

関連する問題