Javascript Node.js通过回调返回多个错误的约定?

Javascript Node.js通过回调返回多个错误的约定?,javascript,node.js,error-handling,Javascript,Node.js,Error Handling,因此,Node.js中回调函数的作用是为错误“保留”第一个参数(如果存在)。例如: callSomeBlockingFcn( function callbackWhenDone(err, result) { if( err ) ... }); 如果需要返回多个错误(例如,多个数据验证错误),传递错误对象数组是否被认为是糟糕的形式?例如: var callSomeBlockingFcn = function(callback) { // multiple errors to report

因此,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, ...] } );
}
还是最好避免使用数组并返回一个包含引用数组的属性的单个对象(如果需要)?例如:

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, ...] } );
}

3年后

任何在回调中放入数组的人都会让我发疯

正确的解决方案是返回一个
错误
作为第一个参数。如果您想返回多个错误,您可能会在非异常情况下使用错误

在这种情况下,它应该放在回调的“value”槽中,即第二个参数。第一个参数用于单个意外的操作错误

如果您有多个意外的操作错误(不太可能),您可以这样做

原件

我认为返回一系列错误没有什么错

尽管您可以返回一个新的自定义
ValidationError
,它有一个属性
“messages”
,该属性是一个数组

(a)

(b)


通过搜索同一问题找到此问题。虽然我环顾四周,得出结论,我不相信
err
应该是错误或
null

我找到的最好的“权威”来源是Nodejitsu的帮助主题:

在node.js中,通过将异步函数中的错误作为当前函数回调的第一个参数返回,处理异步函数中的错误被视为标准做法。如果有错误,第一个参数将传递一个包含所有详细信息的错误对象。否则,第一个参数为null

但我认为你可以从直觉的角度来论证为什么会这样。虽然在代码中有很多
if(err)
测试来确定某个内容是否是错误,但您不应该通过
0
false
未定义的
NaN
或空字符串。如果愿意,您应该能够使用
if(err==null)
进行测试

在err字段中传回非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
数组,如果他们愿意的话。

我不赞成你的观点“我认为返回一系列错误没有什么错”,但是奖励你100分(因为当我奖励它以吸引更多的注意力时,没有其他人回答,所以我没有其他人给予分数)。也许98分的净收益将是重新审视和思考这个问题的一个小小的激励:-P…因为我确实认为经典是,一系列错误不是节点中有效的错误参数。@HostileFork挑战被接受:)修复了答案。@Raynos投票相应地得到了更正。验证是值得的。:-)AggregateError呢r对象?而不是
MultipleError.prototype.\uuu-proto\uuuu
,您可能需要执行
MultipleError.prototype=object.create(Error.prototype,{constructor:{value:MultipleError},name:{value:'MultipleError'},toString:{value:function(){/…})
,另外还有一个额外的好处,就是使那些属性在
MultipleError
上不可配置和不可枚举。