简体   繁体   中英

Nodejs not able to respond to more than one request for mongoose connection test

I'm fairly new to mongoose and node. I am trying to write a simple API using Nodejs and Express, wherein I send a MongoDB URI, and if it is valid, ie the username/password combo works and a connection to that URI is successfully established, a success message should be returned.

I initially tried to create a separate function to try to connect to the given URI:

function testURI(uri) {
   mongoose.connect(uri, {useNewUrlParser: true} );
   mongoose.connection.on("connected", function() { return true } );
}

module.exports.test = function(req, res) {
   var uri = req.body.uri;
   if(testURI(uri)) res.status(200).json({'success': true});
   else res.status(400).json({'success': false});
};

But this failed, since mongoose connects asyncronously, and the "connected" event callback is not able to return true for the main function

So I dropped the idea for a separate function, and instead tried to achieve it within the module.exports.test function:

module.exports.test = function(req, res) {
   var uri = req.body.uri;
   mongoose.connect(uri, { useNewUrlParser: true, connectTimeoutMS: 2500 });

   mongoose.connection.on("connected", function() {
       mongoose.connection.close();
       res.status(200).json({'success': true});
   });

 mongoose.connection.on("error", function(err) {
        result = {
            'error': true,
            'errorMsg': 'Error: Could not connect to the given host.'
        }
        mongoose.connection.close();
        res.status(400).json(result);
    });
};

This works fine, except that the server dies after responding to one request. Once I try with an invalid URI, it returns HTTP 400 as expected, but then when I send another request with a different URI, the app just crashes with the error

Error: Can't set headers after they are sent.

And then I have to restart the app before I can send another request. Apparently the two separate res.status(200).json and res.status(400).json in the same controller are creating the problem and the app is treating subsequent requests also as the same request.

Fixed the problem by creating a custom middleware. Instead of returning the result via res.status().json() within the controller function, I used this function as a middleware and returned the result from the next function

module.exports.test = function(req, res, next) {
   var uri = req.body.uri;
   mongoose.connect(uri, { useNewUrlParser: true, connectTimeoutMS: 2500 });

   mongoose.connection.on("connected", function() {
       mongoose.connection.close();
       req.status = 200;
       req.result = {'success': true};
       next();
   });

 mongoose.connection.on("error", function(err) {
        result = {
            'error': true,
            'errorMsg': 'Error: Could not connect to the given host.'
        }
        mongoose.connection.close();
        req.status = 400;
        req.result = result;
        next();
    });
};

module.exports.returnDb = function(req, res) {
    res.status(req.status).json(req.result);
};

Edited route declaration:

router.route('/test')
.post(client.test, client.returnDb);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM