Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mongoose promise uncaught exception #3355

Closed
perrin4869 opened this issue Sep 8, 2015 · 2 comments
Closed

Mongoose promise uncaught exception #3355

perrin4869 opened this issue Sep 8, 2015 · 2 comments

Comments

@perrin4869
Copy link

I finally got around to promisifying the application I'm working on, and I stumbled upon the following bug when saving a duplicate record with a callback instead of a promise. I added sample code below reproducing the error: when attempting a duplicate insert with a promise and a catch, nothing special happens, but when doing it with a callback it outputs an uncaught exception.

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

UserSchema = new mongoose.Schema({
        _id: String
});
User = mongoose.model('User', UserSchema);

mongoose.connect('mongodb://localhost/mongoose_promise', function() {
        var user = new User({ _id: 'a' });
        user.save().then(function(res) {
                var user2 = new User({ _id: 'a' });
                user2.save().catch(function(err) {
                        console.log("Caught error - Promise");
                });

                var user3 = new User({ _id: 'a' });
                user3.save(function(err) {
                        if(err) console.log("Caught error - Callback");
                });
        });
});

Output:

Caught error - Promise
Caught error - Callback
Unhandled rejection MongoError: E11000 duplicate key error index: mongoose_promise.users.$_id_ dup key: { : "a" }
    at Function.MongoError.create (/home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/error.js:31:11)
    at toError (/home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/lib/utils.js:113:22)
    at /home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/lib/collection.js:547:23
    at /home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/lib/bulk/unordered.js:457:9
    at resultHandler (/home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/lib/bulk/unordered.js:409:5)
    at /home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:756:13
    at Callbacks.emit (/home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:95:3)
    at null.messageHandler (/home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:243:23)
    at Socket.<anonymous> (/home/perrin4869/projects/nodejs/mongoose_promise/node_modules/mongoose/node_modules/mongodb/node_modules/mongodb-core/lib/connection/connection.js:262:22)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
    at TCP.onread (net.js:538:20)

If you remove the line mongoose.Promise = Promise; then the callback stops outputting the message.

@vkarpov15 vkarpov15 added this to the 4.1.7 milestone Sep 8, 2015
@vkarpov15
Copy link
Collaborator

For backwards compat until #2917, mongoose returns mpromise promises, which do not have a .catch(). Feel free to nag for that at aheckmann/mpromise#14, however, its not a priority going forward since mongoose will no longer support mpromise in its next major release. I would strongly recommend you set mongoose's promise lib with mongoose.Promise = global.Promise; or similar if you want to use mongoose with promises.

The reason why you're not getting any messages if you don't use an ES6-compatible promises lib like Bluebird is that the user2.save().catch() call crashes out and rejects the promise. For instance, if you run the below script:

var mongoose = require('mongoose'),
        Promise  = require('bluebird');
//mongoose.Promise = Promise;

mongoose.set('debug', true);

UserSchema = new mongoose.Schema({
        _id: String
});
User = mongoose.model('User', UserSchema);

mongoose.connect('mongodb://localhost/gh3355', function() {
  User.remove(function() {
    next();
  });
});

function next() {
        var user = new User({ _id: 'a' });
        user.save().then(function(res) {
                var user2 = new User({ _id: 'a' });
                user2.save().catch(function(err) {
                        console.log("Caught error - Promise");
                });
                console.log(1);

                var user3 = new User({ _id: 'a' });
                user3.save(function(err) {
                        if(err) console.log("Caught error - Callback");
                });
        }).then(null, function(error) { console.log(error.stack); });
}

You should see the error:

TypeError: undefined is not a function
    at /home/val/Workspace/10gen/troubleshoot-mongoose/gh-3355.js:22:35
    at newTickHandler (/home/val/Workspace/10gen/mongoose/node_modules/mpromise/lib/promise.js:229:18)
    at process._tickCallback (node.js:355:11)

@vkarpov15 vkarpov15 removed this from the 4.1.7 milestone Sep 11, 2015
@kog13
Copy link

kog13 commented Oct 6, 2015

@vkarpov15 mongoose.Promise = global.Promise was exactly what I was looking for. Thank you so much for the recommendation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants