10

I'm going through a few error scenarios, trying to understand how to handle those.

In the case where there is no database connection, a Mongoose Model.find(...) call seems to hang. Below the example code. I would have assumed that the callback is invoked with an err object, but it is not.

How can I prevent the model call to hang? Do I manually have to check the readyState each time I access a model?

// app.js
// Let's use a non-existing host so connecting fails:
// (callback is invoked with err object)
mongoose.connect('mongodb://localhostXXX/blog', function(err){ ... });

BlogPost  = mongoose.model('BlogPost', BlogPostSchema);

// api.js
exports.list_posts = function(req, res) {

    // Ready state is '0' = disconnected (since we used a wrong hostname)   
    console.log('DB ready state: ' + BlogPost.db.readyState);

    // This will not invoke the callback:
    BlogPost.find(function(err, threads) {
        // Never called...
    });
 }
Mark
  • 6,647
  • 1
  • 45
  • 88

3 Answers3

6

It is not an answer, but hope it will help you to find solution. Had very similar issue with mongoose.createConnection while using passport module, found out that it works fine with mongoose.connect

bFunc
  • 1,370
  • 1
  • 12
  • 22
  • 2
    I'd give this a +100 if I could. I've been trying to solve this problem for hours. – Tyler Durden Oct 02 '14 at 19:33
  • Thank you so much for this. I wouldn't have been able to figure out for years. This answers explains the difference http://stackoverflow.com/questions/22786374/queries-hang-when-using-mongoose-createconnection-vs-mongoose-connect#answer-22838614. And I've just submitted an issue https://github.com/Automattic/mongoose/issues/4413 – cortopy Aug 14 '16 at 09:59
4

Since you're already using an error handler in the connect call, a sensible thing would be to quit your app when the DB is not up, or activate some middleware that responds with a pretty 500 Internal Server Error.

Mongoose uses node-mongodb-native under the hood for connections to mongodb, you might find other useful connection options in there. :)

EDIT: try setting socketOptions.socketTimeoutMS. Apparently there is no default timeout set. See http://mongodb.github.com/node-mongodb-native/api-generated/server.html.

I don't have node on my work machine to try out the exact syntax for you, but you will probably have to use mongoose.Connection, which has an open() method that accepts options to pass through to node-mongodb-native. I don't think mongoose.connect() accepts these options, but I could be wrong.

rdrey
  • 9,379
  • 4
  • 40
  • 52
  • What about the case where the database goes down after the server has been started? The initial connection will succeed, but wouldn't later calls to `find()` block as I described above? – Mark Jul 23 '12 at 13:45
  • i've done a little more research, see edit. but take this with a grain of salt until I can test your problem later. :) – rdrey Jul 23 '12 at 14:36
  • As I understand it, mongo/mongoose is buffering the `find` until the db reconnects. I believe default options it will attempt to auto-reconnect. In the particular OP example, you want need to check you had a valid initial connection. – dule Nov 07 '13 at 13:33
0

In order to solve this problem you need to do 3 tasks:

  1. Configure the bufferMaxEntries:0 in the options.db section (for more details see here) So when disable bufferMaxEntries this causes mongoose to stop buffer commands and retrying to send them when the server is down.

  2. Configure the autoReconnect:false in the options.db section disable autoReconnet in the db level. (see more information here)

  3. if you are working with mongodb replicaset then you need to disable bufferCommands in the schema level (for each schema you create)

    var schema = new Schema({..}, { bufferCommands: false });

Tal Avissar
  • 10,088
  • 6
  • 45
  • 70