How to rerun the request handler in node + express?

I am running node + express + mongojs. Here is a sample code:

function mongoCallback(req, res) {
  "use strict";
  return function (err, o) {
    if (err) {
      res.send(500, err.message);
    } else if (!o) {
      res.send(404);
    } else {
      res.send(o);
    }
  };
}

var express, app, params, mongo, db;

express = require('express');
params = require('express-params');
app = express();
params.extend(app);

app.use("/", express.static('web'));

mongo = require('mongojs');

db = mongo.connect('mydb', ['inventory']);

app.get('/api/inventory', function (req, res) {
  db.inventory.find(mongoCallback(req, res));
});

app.listen(8000);
console.log('Listening on port 8000');

Sometimes I forget running mongod and an attempt to talk to the database fails with "failed to connect to ..." error. The problem is that starting mongod is not enough, the already existing db object seems to remember that no connection could be made and so the server continues to fail, even if mongod is already running.

So, I have come up with the following solution:

var express, app, params, mongo, db, api;

if (!String.prototype.startsWith) {
  String.prototype.startsWith = function (str) {
    "use strict";
    return this.lastIndexOf(str, 0) === 0;
  };
}

function setDB() {
  db = mongo.connect('IF', ['invoices', 'const', 'inventory']);
}

function mongoCallback(req, res, next, caller, secondTry) {
  return function (err, o) {
    if (err) {
      if (!secondTry && err.message && err.message.startsWith("failed to connect to")) {
        setDB();
        caller(req, res, next, true);
      } else {
        res.send(500, err.message);
      }
    } else if (!o) {
      res.send(404);
    } else {
      res.send(o);
    }
  };
}

express = require('express');
params = require('express-params');
app = express();
params.extend(app);

app.use("/", express["static"]('web'));

mongo = require('mongojs');

setDB();

api = {
  getInventory: function (req, res, next, secondTry) {
    db.inventory.find(mongoCallback(req, res, next, api.getInventory, secondTry));
  }
};

app.get('/api/inventory', api.getInventory);

app.listen(8000);
console.log('Listening on port 8000');

Basically it recreates the db object if a request fails with the "failed to connect to" error and reruns the request. This is done only for the first failure. A subsequent failure returns the error.

I do not like my solution at all. There has to be a better way. Any suggestions?

Thanks.

What do you mean by "the already existing db object seems to remember that no connection could be made"? Do you mean that the queries on the database fail if you start the express app before running mongod? Since you are connecting to the DB at the startup of the express app, you should have the mongod running first.

If you are worried about the database going down after the initial connection and causing your CRUD operations to fail, you can check for an error in your operations

db.inventory.find(function(err, docs) {
    // check err to see if there was a connection issue
});

and then reconnect if there was an error.

As far as I know the mongodb native driver allows to set { auto_reconnect:true }, have you tried to set this?

I'm not sure how this behaves if the database wasn't running at all, mongoose.js for example caches all requests until the DB is ready and issues them after a successful connection.