Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference error is not thrown from MongoDB callback

Introduction

All people know that if we call undefined.test we will receive the following error (same for both: NodeJS and Javascript):

$ node
> undefined.test
TypeError: Cannot read property 'test' of undefined
    at repl:1:11
    at REPLServer.self.eval (repl.js:110:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
    at ReadStream.EventEmitter.emit (events.js:98:17)
    at emitKey (readline.js:1095:12)

That's correct!

How did I find the problem?

Passed week I wasted about 30 minutes in debugging the following problem: A script was stopping accidentally and no error was thrown.

I had the urls variable that was supposed to be an object:

var urls = settings.urls || {}; 

Then in next lines I needed to get shop key of urls that was a string:

var shop = urls.shop || "/";

I started adding console.log to find the values of variables:

console.log(urls);            // undefined
var shop = urls.shop || "/";
console.log("Passed");        // This isn't run.

The problem in my script was that I was redefining a new urls variable that was making the urls undefined, but the question is: why cannot read property "shop" of undefined didn't appear here? Because urls was really undefined.

We know that the following is happening in both: NodeJS and Javascript:

 var a = 10;
 foo(function () {
     console.log(a); // undefined
     var a = 10;
 });
 function foo(callback) { callback(); } 

The question

After debugging the problem I found that this problem comes from Mongo: inside of Mongo callbacks if we call undefined.something we DON'T get the error.

I've created a small script that demonstrates this:

var mongo = require("mongodb");

// Mongo server
var server = mongo.Server("127.0.0.1", 27017);
var db = new mongo.Db("test", server, { safe: true });

console.log("> START");

// Open database
console.log("Opening database.");
db.open(function(err, db) {
    if (err) { return console.log("Cannot open database."); }

    // get collection
    console.log("No error. Opening collection.");
    db.collection("col_one", function(err, collection) {
        if(err) { return console.log(err) }

        // do something with the collection
        console.log("No error. Finding all items from collection.");
        collection.find().toArray(function(err, items) {
            if(err) { return console.log(err) }

            console.log("No error. Items: ", items);
            console.log("The following line is: undefined.shop." +
            "It will stop the process.");
            console.log(undefined.test); // THE ERROR DOES NOT APPEAR!
            console.log("> STOP"); // this message doesn't appear.
        });
    });
});

My questions are:

  1. Why the error doesn't appear? Which is the reason? (It would be great to debug together the MongoDB source code to find it.)
  2. Why the process is stopped when calling undefined.something?
  3. How can be this solved?

I've created a Github repository where you can download my small application that demonstrates the issue.


Interesting:

If we add a try {} catch (e) {} statement we find the error and the process continue showing the STOP message.

try {
    console.log(undefined.test);
} catch (e) {
    console.log(e);
}

LOGS:

> START
Opening database.
No error. Opening collection.
No error. Finding all items from collection.
No error. Items:  []
The following line is: undefined.shop. It will stop the process.
[TypeError: Cannot read property 'test' of undefined]
> STOP
like image 571
Ionică Bizău Avatar asked Nov 01 '22 16:11

Ionică Bizău


1 Answers

Looking on github.com at node-mongodb-native driver issues, you will notice that issue is solved in 1.3.18 version. But, I tested it and it does not work as expected.

like image 101
Calin Avatar answered Nov 15 '22 06:11

Calin