mongoose.connect(uri, opts) does not return a promise

Created on 26 Oct 2016  路  9Comments  路  Source: Automattic/mongoose

when passing two arguments to mongoose.connect and expecting a promise to be returned, there is simply no promise returned and an error is thrown

for example:

await mongoose.connect(config.mongodb, config.mongodbOptions);

will throw the error

TypeError: this.$opPromise.then is not a function
    at MongooseThenable.then (/Users/nexus/Public/crocodile/node_modules/mongoose/lib/index.js:785:26)
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)
    at Module.runMain (module.js:606:11)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3

but without the second argument, it does not throw the error

await mongoose.connect(config.mongodb);

works fine

cc @vkarpov15

All 9 comments

it looks like the alternate solution until this is fixed is to append the options to your URI such as

mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test&connectTimeoutMS=300000

https://docs.mongodb.com/manual/reference/connection-string/#connections-connection-options

Not sure how to pass { server: ... } server options in a URI - I don't think this is possible? Anyways another workaround is await mongoose.connect(config.mongodb, config.mongodbOptions).then; which seems to work OK.

This happened to me when two test cases each tried to mongoose.connect(...). The second time it failed with the same error as in the first comment. The first connect was successful. Just FYI, I am using bluebird's Promise by setting mongoose.Promise.

I've worked around by preventing "double connect" in this particular case, but in general I'm not sure what the solution is or why it's failing like this.

Actually, I think it's one tiny bit more complicated. If you have:

mongoose.connection.on('error', err => { something(err); });

Then the failure to re-connect ("Trying to open unclosed connection.") does not throw, and in this scenario, mongoose.connect fails to return a valid promise or promise-like object.

Without the error handler installed, the second connect will throw, and so there is no return value.

@niftylettuce can you provide a more thorough code sample and clarify which version of mongoose? I don't see any errors when I run:

'use strict';

var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/gh4659', { server: { reconnectTries: 5 } }).then(res => console.log(res));

@vkarpov15 you can see my issue here - https://github.com/crocodilejs/crocodile-node-mvc-framework/blob/development/src/helpers/mongoose.js - I have to add the .then otherwise it does not work and gives this error

The issue is that mongoose.connect() does not return a promise when there's an error. If there's no 'on error' handler, then the method will throw, which hides the bug. If there's an error handler installed, it breaks.

See this line as an example of incorrect return value:

https://github.com/Automattic/mongoose/blob/master/lib/connection.js#L239

Here's a test case.

var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
var url = 'mongodb://localhost/gh4659';

mongoose.connect(url)
    .then(() => {
        mongoose.connection.on('error', err => {
            console.log('mongoose connection error: '+err);
        });

        console.log('connected - attempting reconnect');
        return mongoose.connect(url);
    })
    .catch(err => {
        console.log('rejected promise: '+err);
        mongoose.disconnect();
    });
;

Actually that example also covers it a bit because bluebird translates the exception thrown: this.$opPromise.then is not a function into a rejection automatically - but you can see how it demonstrates the issue I hope. If you need further clarification I can rework this a bit more.

Thanks @vkarpov15

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

Soviut picture Soviut  路  3Comments

simonxca picture simonxca  路  3Comments

p3x-robot picture p3x-robot  路  3Comments

Igorpollo picture Igorpollo  路  3Comments