Node.js соглашение для возврата нескольких ошибок через обратный вызов?
Итак, общее соглашение для функций обратного вызова в 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, ...] } );
}
Ответы
Ответ 1
спустя 3 года:
Любой, кто помещает массив в обратный вызов, сойдет с ума.
Правильное решение - вернуть error
в качестве первого аргумента. Если вы хотите возвратить несколько ошибок, вероятно, вы используете ошибки для не исключительных случаев.
В этом случае он должен идти в слове "значение" обратного вызова, то есть во втором аргументе. Первый аргумент - для одной неожиданной оперативной ошибки.
Если у вас несколько неожиданных операционных ошибок (маловероятно), вы можете сделать что-то вроде этого MultiError
Оригинал
Я думаю, что нет ничего плохого в возвращении массива ошибок.
Хотя вы можете вернуть новый пользовательский ValidationError
, у которого есть свойство "messages"
, которое является массивом.
а)
function validateX(x, cb) {
...
if (errorMessages) {
return cb(errorMessages);
}
}
б)
function ValidationError(msgs) {
this.messages = msgs;
}
function validateX(x, cb) {
...
if (errorMessages) {
return cb(new ValidationError(errorMessages));
}
}
Ответ 2
Нашел этот вопрос, выполнив поиск по той же проблеме. Хотя я огляделся и пришел к выводу, что я не считаю, что err
должен быть чем-то вроде ошибки или null
.
Лучший "авторитетный" источник, который я нашел, это тема справки Nodejitsu:
http://docs.nodejitsu.com/articles/errors/what-are-the-error-conventions
В node.js считается стандартной практикой обрабатывать ошибки в асинхронных функциях, возвращая их в качестве первого аргумента для текущего обратного вызова функции. Если есть ошибка, первый параметр передается объекту Error со всеми подробностями. В противном случае первый параметр имеет значение null.
Но я думаю, что вы можете сделать аргумент из интуиции о том, почему это так. Хотя в коде есть много тестов if (err)
, чтобы решить, что-то было или не было ошибкой, вы не должны передавать 0
или false
или undefined
или NaN
или пустую строку. Вы должны быть в состоянии проверить с помощью if (err == null)
, если хотите.
Передача чего-то в поле err, которое не является нулевым, но не соответствует 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
, если они хотят.