user3188325 user3188325 - 11 months ago 82
Node.js Question

MongoDB Node.js driver: callback does not handle exceptions on insert

w3school gives a simple example of inserting an object into a database, but in this example the callback seems not to catch some exceptions and I cannot understand why.

On this modified example,

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/mydb";

MongoClient.connect(url, function(err, db) {
if (err) throw err;
// var myobj = { name: "Company Inc", address: "Highway 37" };
var myobj; // undefined
db.collection("customers").insertOne(myobj, function(err, res) {
if (err) console.log('Error: We should see this');
console.log("1 document inserted");
db.close();
});
});


I am trying to insert an undefined object into a collection and expect the callback to handle the exception by printing out the text ('Error: We should see this').

Instead, the following exception is thrown and the program terminates (as if the whole
connect
expects to be wrapped by try/catch block).

TypeError: Cannot read property '_id' of undefined


Can someone, please, explain why this is happening?

Thanks!

Answer Source

Before running the actual insertOne command against the MongoDb server, the _id property of the document you are trying to insert is accessed to see if it is currently 0. You can see this happening in the source code.

The key point here is that this is before the asynchronous processing of the insertOne request begins - The error has not occurred during the actual insert process, but rather during a pre-check on the doc argument. The code assumes that you have not provided a null/undefined document, which in this case is not a correct assumption.

Obviously, you can check the document before you pass it in - ensuring that it is not null/undefined - This would be sensible. Otherwise, you could wrap just the insertOne call in a try/catch:

MongoClient.connect(url, function(err, db) {
    if (err) throw err;
    // var myobj = { name: "Company Inc", address: "Highway 37" };
    var myobj;       // undefined

    try {
        db.collection("customers").insertOne(myobj, function(err, res) {
            if (err) console.log('Error: We should see this');
            console.log("1 document inserted");
            db.close();
        });
    } catch (e) {
        ...
    }
});

I'd go with the approach of checking the document is valid before sending it into insertOne. You have full control of this and wouldn't need the try/catch.

In summary, the approach you show is somewhat of a misuse of the driver.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download