Javascript 在 node.js 中抛出错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33086247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Throwing an error in node.js
提问by Costa
I've got a tiny module that acts as a model for my data. It sits between my routes and my database for particular data (user data in my case).
我有一个小模块作为我的数据模型。它位于我的路线和我的特定数据数据库之间(在我的例子中是用户数据)。
I require this module in my route code, call the subscribe
method that it has, and that subscribes a user to a particular mailing list, by storing the needed data in my database. Yay!
我需要在我的路由代码中使用这个模块,调用subscribe
它拥有的方法,并通过将所需的数据存储在我的数据库中来为用户订阅特定的邮件列表。好极了!
My 'subscribe' method accepts an email and an email list ID as the two parameters. It's reasonable that I'll code sloppy and fast and put in an id for a list that doesn't exist. Spelling error, you name it.
我的“订阅”方法接受电子邮件和电子邮件列表 ID 作为两个参数。我会草率而快速地编写代码并为一个不存在的列表输入一个 id 是合理的。拼写错误,随便你说。
How can I throw an error and point to the line number with that incorrect id?
如何抛出错误并指向具有该错误 ID 的行号?
Code from inside model/user.js:
来自模型/user.js 的代码:
if (emailLists.indexOf(listId) === -1) {
throw new Error('listId does not exist');
}
Code from inside route.js:
来自 route.js 的代码:
user.subscribe('[email protected]', 'knewsletterr', function (error, success) {
if (error) { return sendResponse(500, 'Ahhhhhhh!'); }
if (!error) { return sendResponse(200, 'subscribed'); }
});
Right now, I'm getting:
现在,我得到:
/home/.../project/models/user.js:85
if (emailLists.indexOf(listId) === -1) { throw new Error('listId does not exist'); }
^
Error: listId does not exist
回答by Thank you
If you're using node-style callbacks, the convention isn't to throw
, instead pass you error as the first argument to your callback
如果您使用节点样式的回调,则约定不是 to 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)
})
Kind of a stupid function to use a callback since it can be written in a purely synchronous way, but hopefully this illustrates the pattern
使用回调是一种愚蠢的函数,因为它可以以纯同步方式编写,但希望这说明了该模式
Your function might already be written in a synchronous way – don't worry tho, we can convert it to a node-style callback function using something like cps2
below
您的函数可能已经以同步方式编写 - 别担心,我们可以使用如下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
All of that said, most peoples are using Promises nowadays. Below we demonstrate how to turn a node-style callback function into one that returns a Promise. Note, node
provides this function as util.promisify
, though I've implemented it here for demonstration purposes -
综上所述,如今大多数人都在使用 Promise。下面我们演示如何将节点样式的回调函数转换为返回 Promise 的回调函数。请注意,node
将此功能提供为util.promisify
,但我已在此处实现它以进行演示 -
// a conventional function with a node-style callback
const div = (x, y, done) =>
{ if (y === 0)
return done (Error ('cannot divide by zero'))
else
return done (null, x / y)
}
// convert a node-style callback function to a promise-returning function
const promisify = f => (...args) =>
new Promise
( (resolve, reject) =>
f ( ...args
, (err, result) =>
err
? reject (err)
: resolve (result)
)
)
// logging utility for demos below
const logger = p =>
p .then (console.log, console.error)
logger (promisify (div) (6, 3))
// 2
logger (promisify (div) (6, 0))
// Error: cannot divide by zero
Continuations are just functions tho so you can write this kind of thing in any way that you like – don't think you have to use node-style "callbacks" or Promises just because that's the only way you've seen it
延续只是函数,所以你可以用任何你喜欢的方式来写这种东西——不要认为你必须使用节点样式的“回调”或承诺,因为这是你见过的唯一方式
const cont = (...values) =>
k => k (...values)
const div = (x, y) =>
y === 0
? cont (Error ('cannot divide by zero'))
: cont (null, x / y)
const logger = (err, result) =>
err
? console .log ('error:', err.message)
: console .log ('result:', result)
div (6, 3) (logger)
// result: 2
div (6, 0) (logger)
// error: cannot divide by zero