2015-10-12 3 views
5

У меня есть крошечный модуль, который действует как модель для моих данных. Он находится между моими маршрутами и моей базой данных для конкретных данных (данные пользователя в моем случае).Выбрасывание ошибки в node.js

Мне нужен этот модуль в коде маршрута, вызывается метод subscribe, который у него есть, и который подписывает пользователя на конкретный список рассылки, сохраняя необходимые данные в моей базе данных. Ура!

Метод «подписаться» принимает адрес электронной почты и идентификатор списка адресов электронной почты в качестве двух параметров. Разумно, что я буду делать код неаккуратно и быстро, и введите идентификатор для списка, который не существует. Неправильная ошибка.

Как я могу сбросить ошибку и указать номер строки с этим неправильным идентификатором?

Код с внутренней модели/user.js:

if (emailLists.indexOf(listId) === -1) { 
    throw new Error('listId does not exist'); 
} 

Код с внутренней route.js:

user.subscribe('[email protected]', '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 
+0

listId переменная не указана в вашем исходном коде –

+0

Ха-ха, я знаю. Я тот, кто бросает ошибку. Я просто хочу знать, как выкинуть соответствующий номер строки и имя файла вместе с ошибкой. – Costa

+1

var e = new Ошибка ("asdf"); console.log (e.stack) –

ответ

7

Если вы используете обратные вызовы узла стиля, конвенция является не 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


Продолжения являются только функции Тхо, так что вы можете написать такого рода вещи в любом случае, что вам нравится - не думаю, вы должны использовать узел в стиле «обратных вызовов» или Promises только потому, что это единственный способ, которым вы уже видели это

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

+0

Спасибо, это полезно! Это первый подход, который я принял, но я делаю три разные вещи в зависимости от того, что происходит, когда вы подписываетесь на кого-то («уже подписанный», «успех», «некоторая другая ошибка»), поэтому было сложно разделить понятия концептуально. Возможно, я должен просто лечить ошибку, так как приложение не будет запускать ошибки и, как правило, обрабатывать результаты для всего остального. – Costa

+0

Вообще говоря, 'throw' - синхронный метод обработки ошибок. При использовании обратных вызовов предполагается, что вы имеете дело с асинхронным кодом, где 'throw' не будет особенно полезен. Идея заключается в том, что вам не нужно ловить «err» в каждом обратном вызове в вашей цепочке. Если вы не хотите обрабатывать ошибку в середине, вы можете просто передать ее по 'done (err, x);' Если 'err' является' null', ничего не произойдет, но если 'err' является' Ошибка', функция выше имеет шанс поймать ее. – naomik

+1

Все это говорит о том, что это не лучший способ разработки async-ошибок. Это просто соглашение в узле, и поэтому, вероятно, это лучший выбор * если * вы пишете приложение/lib, которое другие будут использовать.Если вы просто пишете приложение для себя, вы можете спроектировать обработку ошибок, но вы считаете, что это лучше всего для вас, и просто используйте соглашение с узлом, в котором вы взаимодействуете с другими библиотеками. – naomik

2

This Вам поможет !

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>

+0

Спасибо, я прочитал эту страницу MDN. Это трассировка стека node.js. Я думаю, что у меня проблемы. Я признаю, что я немного смущен в этот момент. – Costa

+1

so: https://www.joyent.com/developers/node/design/errors#appendix-conventional-properties-for-error-objects – Anonymous0day

Смежные вопросы