Mongo db with Monk: error detection and handling if db is omitted

I am new to Mongo. I need a database for a simple project and I ended up with a tutorial using Mongo with Monk, but I am having trouble understanding how to handle errors.

Background . I have a client side registration form. When the user clicks the button, the data is sent via AJAX to the controller, which (after validation, but now it doesn't matter) inserts such data into the database and sends back either success or an error. When db everything works, everything works fine.

Problem . If I don't start db and try to submit the request anyway, no error will be returned. Nothing just happens. After a while on the console I get: POST / members / addmember - - ms - -.

I think some error should be returned to the user in this case, so how can I do that?

Post request below (mostly like from the tutorial):

// app.js 

var db = monk('localhost:27017/dbname')
[...]
// I realize it might be not optimal here
app.use(function(req,res,next){ 
    req.db = db;
    next();
});

// members.js

router.post('/addmember', function(req, res) {
  var db = req.db;
  var collection = db.get('memberstest');
  collection.insert(req.body, function(err, result){
    res.json(
      (err === null) ? { msg: 'success' } : { msg: err }
    );
  });
});

      

If the db doesn't work, I think the problem is actually even earlier than the insert, that is, in "db.get ()". So how do you check if this can actually be done? I suppose with the asynchronous nature of node, something like try / catch would be useless here. Right?

EDIT: After Neil answered and tried a little, I put together the following that seems to do the job. However, given my limited degree of confidence in this, I would appreciate a comment if the code below works because it makes sense or is accidental. I added options to bufferMaxEntries: 0 and modified the controller as follows. In the ajax callback, I just have an alert that shows the error message (if any).

router.post('/addmember', async (req,res) => {

    try {
      let db = req.db;
      let collection = db.get('memberstest');

      collection.insert(req.body, function(err, result){
      res.json(
        (err === null) ? { msg: 'success' } : { msg: err }
      );
    });

    await db.then(() => 1);

    } catch(e) {
      res.json({msg: e.message})
    }

});

      

+3


source to share


1 answer


Well, you can actually set a parameter bufferMaxEntries

(documented Db

but deprecated to use this object, use the "top" level as shown in the picture) on a connection that essentially stops "queue" requests to the driver when there is indeed no connection.

As a minimal example:

index.js

const express = require('express'),
      morgan = require('morgan'),
      db = require('monk')('localhost/test',{ bufferMaxEntries: 0 }),
      app = express();

const routes = require('./routes');

app.use(morgan('combined'));

app.use((req,res,next) => {
  req.db = db;
  next();
});

app.use('/', routes);

(async function() {

  try {

    await db.then(() => 1);

    let collection = db.get('test');
    await collection.remove({});

    await collection.insert(Array(5).fill(1).map((e,i) => ({ a: i+1 })));
    console.log('inserted test data');

    await app.listen(3000,'0.0.0.0');
    console.log('App waiting');

  } catch(e) {
    console.error(e);
  }

})();

      

routes.js

var router = require('express').Router();

router.get('/', async (req,res) => {
  try {
    let db = req.db,
        collection = db.get('test');

    let response = await collection.find();
    res.json(response);
  } catch(e) {
    res.status(500).json(e);
  }
});

module.exports = router;

      

So I really expect a database connection to at least be present here, like "run", but really only, for example, since I want to insert some data to actually retrieve. This is not required, but the basic idea is to wait for permission Promise

:

await db.then(() => 1);

      



Kind of trivial and not really necessary for your actual code. But I still think it's good practice.

The real test is performed by stopping mongod

or otherwise making the server unavailable and then issuing a request.

Since we are setting the connection parameters to { bufferMaxEntries: 0 }

, this means that an immediate attempt to issue a command to the database will fail if there is no actual connection.

Of course, when the database becomes available again, you will not get an error and the instructions will run normally.

Without the option, it defaults to "en-queue" the operation until the connection is allowed, and then the "buffer" is essentially "replayed".

You can simulate this (as I did) by "stopping" the daemon mongod

and issuing requests. Then "starting" the daemon and issuing requests. It should simply return the captured error response.

NOTE : not required, but actually the whole purpose of the syntax async/await

is to make things like try..catch

valid again , as you can actually use like blocks rather than use Promise.catch()

or err

callback arguments to catch errors. The same principles apply when any of these structures are actually used.

+1


source







All Articles