Выбрасывание ошибки в узле.JS
У меня есть крошечный модуль, который служит моделью для моих данных. Он находится между моими маршрутами и моей базой данных для конкретных данных (пользовательских данных в моем случае).
Я требую этот модуль в моем коде маршрута, вызываю метод subscribe
, который у него есть, и который подписывает пользователя на определенный список рассылки, сохраняя необходимые данные в моей базе данных. Ура!
Мой метод "subscribe" принимает адрес электронной почты и идентификатор списка адресов электронной почты в качестве двух параметров. Вполне разумно, что я буду кодировать небрежно и быстро и вставлять идентификатор для несуществующего списка. Орфографическая ошибка, как вы ее называете.
Как я могу выдать ошибку и указать на номер строки с этим неправильным идентификатором?
Код из внутренней модели / пользователя.js:
if (emailLists.indexOf(listId) === -1) {
throw new Error('listId does not exist');
}
Код из внутреннего маршрута.js:
user.subscribe('fake@email.com', 'knewsletterr', function (error, success) {
if (error) { return sendResponse(500, 'Ahhhhhhh!'); }
if (!error) { return sendResponse(200, 'subscribed'); }
});
Прямо сейчас я получаю:
/home/.../project/models/user.js:85
if (emailLists.indexOf(listId) === -1) { throw new Error('listId does not exist'); }
^
Error: listId does not exist
2 ответа:
Если вы используете обратные вызовы в стиле узла, соглашение не должно
throw
, вместо этого передайте вам ошибку в качестве первого аргумента для вашего обратного вызова
// divide with callback function div (x, y, done) { if (y === 0) return done (Error ('Cannot divide by zero')) else return done (null, x / y) } div (6, 3, function (err, result) { // *always* check for err if (err) console.log ('error', err.message, err.stack) else console.log ('result', result) })
Довольно глупо использовать функцию обратного вызова, поскольку она может быть написана чисто синхронно, но, надеюсь, это иллюстрирует шаблон
Ваша функция уже может быть записана синхронно – не волнуйтесь, мы можем преобразовать ее в функцию обратного вызова в стиле узла, используя что-то вроде
cps2
ниже
// a "normal" synchronous function that throws an error const div = (x,y) => { if (y === 0) throw Error ('cannot divide by zero') else return x / y } // convert it to a continuation passing style (cps) function const cps2 = (f, x, y, k) => { try { return k (null, f (x, y)) } catch (err) { return k (err) } } // logging utility for demos below const logger = (err, result) => { if (err) console.log ('error:', err.message, err.stack) else console.log ('result:', result) } cps2 (div, 6, 3, logger) // result: 2 cps2 (div, 6, 0, logger) // error: cannot divide by zero
Все это говорит о том, что большинство людей в настоящее время используют обещания
const div = (x, y, done) => { if (y === 0) return done (Error ('cannot divide by zero')) else return done (null, x / y) } const promisify = f => (...args) => new Promise ((resolve, reject) => f (...args, (err, result) => { if (err) reject (err) else resolve (result) })) const logp = p => p.then (console.log, console.error) logp (promisify (div) (6, 3)) // 2 logp (promisify (div) (6, 0)) // Error: cannot divide by zero
Продолжения-это просто функции, поэтому вы можете писать такие вещи любым способом, который вам нравится – не думайте, что вам нужно использовать "обратные вызовы" в стиле узла или обещания только потому, что это единственный способ, которым вы это видели
const cont = (...values) => k => k (...values) const div = (x, y) => y === 0 ? cont (Error ('cannot divide by zero')) : cont (null, x / y) const log = (err, result) => err ? console.log ('error:', err.message) : console.log ('result:', result) div (6, 3) (log) // result: 2 div (6, 0) (log) // error: cannot divide by zero
Это поможет вам !
var el = document.getElementById('el'); var log = function( val ){ el.innerHTML+= '<div><pre>' + val + '</pre></div>'; }; try { throw Error('error in code'); } catch (e) { log( e.message ); log( e.fileName ); log( e.lineNumber ); log( e.stack ); };
<div id='el'></div>