【问题标题】:Mongoose save() using native promise - how to catch errorsMongoose save() 使用本机承诺 - 如何捕获错误
【发布时间】:2015-10-02 11:08:35
【问题描述】:

我正在尝试使用 Mongoose 的原生 Promise 捕获从 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() 会原生返回一个承诺。

【问题讨论】:

    标签: mongoose promise


    【解决方案1】:

    以下答案是针对 2018 年的人,nodejs 已更改,回调已替换为 async/await。

    我们可以在 Mongoose 中使用“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);
        });
    

    【讨论】:

    • 可以在不声明异步函数的情况下使用 await 吗?为什么要混合 async/await 和 then/catch?
    • 如果没有将函数声明为 async it's not allowed 就不能使用 await 。 Catch 博客用于处理与异步无关的错误
    • 那么关于异步,我可以建议你在你的回答中说清楚吗?关于 .catch() AFAIK,它与 Promise 严格相关。为什么要混合这两种方法?您可以将 async/await 包装在 try/catch 块中
    【解决方案2】:

    Bluebird 实际上并不需要在 Mongoose 中使用 Promise,您可以简单地使用 Node 的原生 Promise,就像这样:

    mongoose.Promise = Promise
    

    【讨论】:

      【解决方案3】:

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

      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')
        }, function(err) {
          // want to handle errors here
        });
      

      更新 1:从 4.1.0 开始,MongooseJS 现在允许 specification of which promise implementation to use:

      是的 require('mongoose').Promise = global.Promise 将使猫鼬使用原生承诺。你应该可以使用任何 ES6 Promise 构造函数,但是现在我们只使用原生、bluebird 和 Q 进行测试

      更新 2:如果您在 4.x 的最新版本中使用 mpromise,您将收到以下贬损警告:

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

      【讨论】:

      • 我应该在所有.then()s 中还是只在最后一个.then() 中创建一个错误处理函数?然后错误会冒泡到最后,还是我必须每次都这样做?
      • 随着错误的不断涌现,这完全取决于您。您可以像现在一样拥有一个包罗万象的方法,或者您可以在第二次保存时添加另一个错误处理程序,例如:....save().then(null, function(err) {...}); 如果需要,您只需要在处理错误后遵循典型的方法来冒泡错误。
      • @steampowered 您的编辑不正确。从 Mongoose 4.11.4(本评论的当前版本)开始,它仍然使用 mpromise 来实现向后兼容性。 2016 年 8 月的更新说明包括您现在选择的答案。
      • mpromise 已被弃用,在最新版本的 Mongoose 中使用它现在总是会抛出错误 DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated。所以是的,它仍然存在向后兼容,但未来的版本可能会删除它。
      • @steampowered 我的观点仍然成立:这个答案对后代和未来仍然有效,因为它已经包含您现在选择作为正确答案的答案(最初提出此问题时不可用,因此更新)。
      【解决方案4】:

      您可以使用 bluebird 在 mongoose 上扩展 Promise 功能

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

      【讨论】:

      • 是的,这是新的正确答案。几年前,其他答案之一是正确的,所以我将正确答案更改为您的答案。
      • 这个答案已经包含在(以前)接受的答案中的更新说明中(除了使用 Bluebird 代替原生 Promise)。
      【解决方案5】:

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

      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
        });
      }
      

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

      【讨论】:

      • 我不熟悉javascript中的=>语法。它叫什么?
      • @steampowered 它只是一种定义函数的新方法。为了更好地理解,我更改了代码。
      • @steampowered:它被称为箭头函数。它们与 ES6 一起提供,就像原生 Promise 一样 :-)
      猜你喜欢
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 2022-12-19
      • 2017-07-11
      • 2017-08-06
      • 2021-03-03
      • 2021-11-28
      • 2018-05-12
      相关资源
      最近更新 更多