Node.js mongodb崩溃节点,在try catch中出现异常
这就在我的代码中产生了一个错误——这没关系,但是为什么即使我在这里有一个try-catch,我的nodejs程序也会崩溃呢 错误是:Node.js mongodb崩溃节点,在try catch中出现异常,node.js,mongodb,coffeescript,Node.js,Mongodb,Coffeescript,这就在我的代码中产生了一个错误——这没关系,但是为什么即使我在这里有一个try-catch,我的nodejs程序也会崩溃呢 错误是: try p = req.params.name Item.update('name': p, req.body , {upsert: true}, (err) -> if err? throw err res.send("ok") ) catch e handle_error(e
try
p = req.params.name
Item.update('name': p, req.body , {upsert: true}, (err) ->
if err?
throw err
res.send("ok")
)
catch e
handle_error(e, "Error salvando hoja de vida.", res)
(因此它必须在更新调用中)
我正在寻找一种捕获错误的方法,我已经知道如何消除它。也许我错了(因为我不知道Coffeescript),但我想问题是,您的try/catch在回调函数之外。捕获不会影响您的err->
,因此异常不是由您捕获的,而是由node.js捕获的
如果我错了,您是否可以提供已编译的JavaScript代码
编辑
通常情况下,人们会更像这样处理错误(不使用try/catch):
您的处理错误
可能已经可以执行此操作
在node.js中编程时,我只对
JSON.parse
使用try/catch,或者如果我有很多未检查的输入,这些输入可能有错误的类型或可能为空,并且我太懒了,无法手动检查所有输入。只有当函数存在编程错误(例如,没有正确检查输入)时,使用try/catch包围异步函数才有帮助。啊,是的,您已经进入了异步代码领域。将回调传递到MongoDB调用(如Item.update(…,callback)
中的原因是,MongoDB驱动程序是异步编写的。考虑这个(猫鼬代码):
如果它像上面的代码那样构造了它的API,那么整个应用程序将停止,直到User.findOne()
从数据库返回结果。您的doSomethingElse()
调用在检索到用户之前不会被调用,即使您没有对doSomethingElse
内部的user
执行任何操作。这是一个很大的禁忌,尤其是在节点中,它已经被尽可能地写为异步。请看以下内容:
var user = User.findOne({ name: 'joe' });
doSomethingElse();
上面的代码是异步的。findOne
函数立即返回,doSomethingElse
甚至在从数据库检索用户之前就可以开始了。当然,我们仍然想对用户做一些事情,所以为了完成这一点,我们传入一个匿名函数作为回调函数。MongoDB驱动程序足够聪明,可以在检索完数据后调用该函数
将上述代码包装在try/catch中是毫无意义的,除非您怀疑findOne
函数抛出异常(您不应该这样做。它会立即返回,还记得吗?)
上面的错误仍然会使您的程序崩溃,因为它发生在findOne
返回后很长一段时间,并且您的程序已经超出了宝贵的try/catch。这就是回调函数接收err
参数的原因。MongoDB驱动程序知道,如果在获取数据时发生错误,抛出异常并称其为good是没有好处的。这是因为所有这些处理都是在事件循环的后续行程中发生的,而您的try/catch在几次迭代之前就已经落后了
为了解决这个问题,MongoDB驱动程序将自己的内部同步代码包装在一个try/catch中,它实际上将处理异常,然后调用回调函数,将错误作为第一个参数传入。这允许您检查该参数并处理回调中的任何错误
我写了一篇完整的博客文章解释回调,以及另一种处理异步代码的方法,称为“承诺”,我认为这将有助于为您澄清一些事情:)
我希望这有助于回答你的问题。谢谢@Alex,它很好地解释了一切——但有些事情对我来说仍然是个谜。如果,如您所说,MongoDB“将自己的内部异步代码包装在一个try/catch中,它实际上将处理异常,然后调用您的回调,将错误作为第一个参数传入。”-为什么程序会因为一个相对无害的错误而完全崩溃,例如“MongoError:Mod on _idnot allowed”。这就是为什么我首先要尝试捕获的原因…我不希望我的程序崩溃!哎呀,我想是因为我重新抛出了错误,希望它被周围的try/catch捕捉到……这是一个死链接answer@StepanYakovenko给你:)
Item.update('name': p, req.body , {upsert: true}, (err) ->
if err?
log.error('error updating Item name=' + name)
res.status(500).end()
return
res.send("ok")
)
var user = User.findOne({ name: 'joe' });
doSomethingElse();
User.findOne({ name: 'joe' }, function (err, user) {
if (err) return console.error(err);
console.log('Do stuff with user... ;)');
});
doSomethingElse();
try {
User.findOne({ name: 'joe' }, function (err, user) {
throw new Error("Something went wrong...");
});
} catch (err) {
console.error(err);
}