Mongoose save()使用本机承诺-如何捕获错误

Mongoose save()使用本机承诺-如何捕获错误,mongoose,promise,Mongoose,Promise,我试图用Mongoose的原生承诺捕捉Mongoose抛出的错误。但我不知道从哪里可以从猫鼬那里得到错误对象 如果可能的话,我希望在.then()s中抛出错误,并在.catch()中捕获错误 var contact = new aircraftContactModel(postVars.contact); contact.save().then(function(){ var aircraft = new aircraftModel(postVars.aircraft); ret

我试图用Mongoose的原生承诺捕捉Mongoose抛出的错误。但我不知道从哪里可以从猫鼬那里得到错误对象

如果可能的话,我希望在
.then()
s中抛出错误,并在
.catch()
中捕获错误

var contact = new aircraftContactModel(postVars.contact);
contact.save().then(function(){
    var aircraft = new aircraftModel(postVars.aircraft);
    return aircraft.save();
})
.then(function(){
    console.log('aircraft saved')
}).catch(function(){
    // want to handle errors here
});
尝试不使用另一个库,因为.save()会以本机方式返回一个承诺。

MongooseJS使用没有
catch()方法的。要捕获错误,可以使用的第二个参数

更新1:从4.1.0开始,MongooseJS现在允许:

是的,
require('mongoose')。Promise=global。Promise
将使mongoose使用本地承诺。不过,您应该能够使用任何ES6 promise构造函数,但现在我们只使用native、bluebird和Q进行测试

更新2:如果您在最新版本的4.x中使用mpromise,您将收到此去润滑警告:

DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated

您可能正在返回save方法创建的承诺,以便在其他地方处理它。 如果是这种情况,您可能希望将错误抛出给父承诺,以便捕获错误。您可以通过以下方式实现:

function saveSchema(doc) {
  return doc.save().then(null, function (err) { 
    throw new Error(err); //Here you are throwing the error to the parent promise
  });
}
function AParentPromise() {
  return new Promise(function (accept, reject) {
    var doc = new MongoSchema({name: 'Jhon'});
    saveSchema(doc).then(function () { // this promise might throw if there is an error
      // by being here the doc is already saved
    });
  }).catch(function(err) {
    console.log(err); // now you can catch an error from saveSchema method
  });
}

我不确定这是否是一种反模式,但这有助于您在一个地方处理错误。

您可以使用
蓝鸟

Promise = require('bluebird');
mongoose.Promise = Promise;

Bluebird实际上不需要在Mongoose中使用承诺,您可以简单地使用Node的本机承诺,如下所示:

mongoose.Promise = Promise

下面的答案是针对2018人的,nodejs现在已经更改,回调被async/await替换

我们可以用“then”来接受猫鼬的承诺

我建议如下答案

await createLogEntry.save().then(result => {
    res.status(200).json({
        status: true,
        message: "log added successfully done"
    })
})
    .catch(error => {
        debugger
        console.log(error);
        next(error);
    });

我应该在所有
.then()
中创建一个错误处理函数,还是只在最后一个
.then()
中创建一个错误处理函数?错误会一直持续到最后吗?还是我必须每一次都这样做?当错误冒出来时,这真的取决于你。您可以一直使用catch,也可以在第二次保存时添加另一个错误处理程序,例如:
…save()。然后(null,function(err){…})如果需要,您只需遵循处理错误后冒泡的典型方法即可。您的编辑不正确。截至Mongoose 4.11.4(截至本评论的当前版本),它仍然使用mpromise实现向后兼容性。2016年8月的更新说明包括您现在选择的答案。mpromise已弃用,在最新版本的Mongoose中使用它将始终引发错误
弃用警告:Mongoose:mpromise(Mongoose的默认承诺库)已弃用
。因此,是的,它仍然存在,以便向后兼容,但将来的版本可能会删除它。@我的观点仍然站得住脚:这个答案对后代和未来仍然有效,因为它已经包含了您现在选择的正确答案(最初提出此问题时不可用,因此更新)。我不熟悉javascript中的
=>
语法。它叫什么?@steampowered这只是定义函数的一种新方法。为了更好地理解,我更改了代码。@steampowered:它叫arrow函数。它们与ES6一起提供,就像本机承诺一样:-)是的,这是新的正确答案。几年前,另一个答案是正确的,因此我将正确答案更改为您的答案。这个答案已经包含在(以前)接受的答案中的更新说明中(除了使用Bluebird而不是本机Promise)。您可以在不声明异步函数的情况下使用Wait吗?为什么要将async/await与then/catch混合使用呢?在没有声明函数的情况下使用await是不可能的,因为它是不允许的。Catch blog是用于处理错误的,它与async没有任何关系。因此,关于async,我建议您在回答中明确说明?还有,这是严格的承诺。为什么要混合使用这两种方法?您可以将async/await包装在try/catch块中
await createLogEntry.save().then(result => {
    res.status(200).json({
        status: true,
        message: "log added successfully done"
    })
})
    .catch(error => {
        debugger
        console.log(error);
        next(error);
    });