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)
这在我的代码中产生了一个错误 - 这没关系,但为什么我的nodejs程序崩溃,即使我在这里试试了?
错误是:
MongoError: Mod on _id not allowed
(所以它必须在更新通话中) 我正在寻找一种捕捉错误的方法,我已经知道如何摆脱它。
答案 0 :(得分:7)
啊,是的,您已进入异步代码领域。将回调传递给MongoDB调用(如Item.update(..., callback)
)的原因是因为MongoDB驱动程序被编写为异步。考虑一下(猫鼬代码):
var user = User.findOne({ name: 'joe' });
doSomethingElse();
如果它像上面的代码那样构建了它的API,那么整个应用程序将暂停,直到User.findOne()
从数据库返回结果。即使您未在doSomethingElse()
内对user
执行任何操作,也不会在检索到用户之前调用doSomethingElse
来电。现在这是一个很大的问题,特别是在尽可能多地写入异步的节点中。看看以下内容:
User.findOne({ name: 'joe' }, function (err, user) {
if (err) return console.error(err);
console.log('Do stuff with user... ;)');
});
doSomethingElse();
上面的代码是异步的。 findOne
函数立即返回 ,doSomethingElse
甚至可以在从数据库中检索用户之前开始。但是我们当然仍然希望对用户做一些事情,所以为了实现这个目的,我们传递一个匿名函数来用作回调。 MongoDB驱动程序非常智能,可以在完成检索数据时调用该函数。
在try / catch中包含上面的代码是没有意义的,除非你怀疑findOne
函数抛出异常(你不应该这样做。它会立即返回吗?)。
try {
User.findOne({ name: 'joe' }, function (err, user) {
throw new Error("Something went wrong...");
});
} catch (err) {
console.error(err);
}
上述错误仍会导致您的程序崩溃,因为它在findOne
返回后很久就发生了,并且您的程序超出了那个宝贵的try / catch。这就是您的回调函数收到err
参数的原因。 MongoDB驱动程序知道如果在获取数据时发生了一些错误,那么抛出异常并将其调用就不错了。这是因为所有这些处理都是在后续的事件循环之后发生的,在几次迭代之前已经将try / catch留在了后面。
为了解决这个问题,MongoDB驱动程序在try / catch中包装它自己的内部同步代码,它实际上将处理异常,然后它调用你的回调传递错误作为第一个参数。这允许您检查该参数并处理回调中的任何错误。
我写了一篇完整的博客文章,解释了回调,以及另一种处理异步代码的方式,称为“promises”,我认为这有助于为你澄清一些事情:) http://codetunnel.io/what-are-callbacks-and-promises
我希望这有助于回答你的问题。
答案 1 :(得分:4)
也许我错了(因为我不知道Coffeescript),但我想问题是,你的try / catch在回调函数之外。捕获不会影响您的err ->
,因此异常不会被您捕获,而是由node.js捕获。
如果我错了,您是否可以提供已编译的JavaScript代码?
修改强>
通常会更像这样处理错误(没有try / catch):
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")
)
可能您的handle_error
已经执行此操作。
在node.js中编程时,我只对JSON.parse
使用 try / catch ,或者如果我有很多未经检查的输入,可能有错误的类型或者可能为null而且我'我懒得手动检查所有输入。使用try / catch的周围异步函数仅在函数有编程错误时才有用(例如,没有正确检查输入)。