11

I am trying to catch errors thrown from Mongoose using Mongoose's native promises. But I don't know where to get the error object from Mongoose.

I would like the errors to be thrown in the .then()s and caught in .catch() if possible.

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

Trying not to use another library, as .save() returns a promise natively.

steampowered
  • 11,809
  • 12
  • 78
  • 98

5 Answers5

29

MongooseJS uses the mpromise library which doesn't have a catch() method. To catch errors you can use the second parameter for 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
  });

UPDATE 1: As of 4.1.0, MongooseJS now allows the specification of which promise implementation to use:

Yup require('mongoose').Promise = global.Promise will make mongoose use native promises. You should be able to use any ES6 promise constructor though, but right now we only test with native, bluebird, and Q

UPDATE 2: If you use mpromise in recent versions of 4.x you will get this deprication warning:

DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated
steampowered
  • 11,809
  • 12
  • 78
  • 98
Jason Cust
  • 10,743
  • 2
  • 33
  • 45
  • Should I create an error handler function in all `.then()`s or just the last `.then()`? Does the error bubble to the last then, or must I do every then? – steampowered Jul 14 '15 at 01:17
  • It's really up to you as errors bubble up. You can have a catchall the way it is now or you can add another error handler on the second save with something like: `....save().then(null, function(err) {...});` You would just need to follow the typical method of bubbling up the error after handling it if need be. – Jason Cust Jul 14 '15 at 01:23
  • @steampowered Your edit is incorrect. As of Mongoose 4.11.4 (current version as of this comment) it still uses mpromise for backwards compatibility. The update note from Aug '16 includes the answer that you have now selected. – Jason Cust Jul 24 '17 at 18:37
  • mpromise is deprecated, and using it in the latest version of Mongoose will now always throw the error `DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated`. So yes, it is still there for backwards compatibility, but future versions will likely remove it. – steampowered Jul 31 '17 at 04:53
  • @steampowered My point still stands: This answer is still valid for both posterity and moving forward as it had already **included** the answer you have now selected as the correct answer (which was not available when this question was originally asked hence the update). – Jason Cust Aug 01 '17 at 19:53
  • at the time I'm writing this comment, mongoose give you a neat way to catch your error just like ``user.save().then(res=>{...}).catch(err=>{...})`` – Shahin Ghasemi Aug 05 '18 at 12:32
  • @ShahinSoft That is correct. Mongoose switched to using the native Promise object and so you can use the exposed methods as you have noticed. – Jason Cust Aug 05 '18 at 13:42
4

you can extend promise functionality on mongoose with bluebird

Promise = require('bluebird');
mongoose.Promise = Promise;
Faizal Pribadi
  • 392
  • 3
  • 5
  • Yes, this is the new correct answer. Years ago one of the other answers was correct, so I changed the correct answer to your answer. – steampowered Jul 19 '17 at 17:02
  • This answer was already covered by the update note in the (previously) accepted answer (aside from using Bluebird instead of native Promise). – Jason Cust Jul 24 '17 at 18:39
1

You are probably returning the promise created by method save to handle it somewhere else. If this is the case, you might want to throw the error to a parent promise where you can catch the error. You can achieve it with this:

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

I am not really sure if this might be an anti-pattern but this help you to handle your errors in one place.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

Bluebird is actually not required to use promises with Mongoose, you can simply use Node's native promises, just like this:

mongoose.Promise = Promise
Pierre C.
  • 1,591
  • 2
  • 16
  • 29
0

following answer is for 2018 people , nodejs is changed now , callback is replaces with async/await.

We can took promises in Mongoose with "then".

i suggest following answer

await createLogEntry.save().then(result => {
    res.status(200).json({
        status: true,
        message: "log added successfully done"
    })
})
    .catch(error => {
        debugger
        console.log(error);
        next(error);
    });
Bhagvat Lande
  • 1,392
  • 3
  • 17
  • 34
  • Can you use await without declaring an async function? And why mix async/await with then/catch? – Neithan Max Oct 07 '18 at 15:58
  • it's not possible to use await without declaration of function as a async it's not allowded . Catch blog is for handling error it's not having any concerns with async – Bhagvat Lande Oct 07 '18 at 17:55
  • So regarding the async, may I suggest you make it clear in your answer? And about .catch() AFAIK it's strictly Promise related. Why mix the two methods? You can wrap the async/await in a try/catch block – Neithan Max Oct 08 '18 at 11:22