5

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
9
  • 1
    you aren't using process.exit properly. It takes a return code (integer), 0 for success and nonzero for failure. This is directly from C and other languages that interact with the command line. Behavior is described here Commented Aug 11, 2013 at 6:20
  • 1
    The > STOP message will not appear because the previous line gives error. Node will stop execution there and throw error. The error message may not show up if you are catching errors or listening to uncaughtException. Is there any error handling in your code ? Commented Aug 11, 2013 at 7:19
  • @user568109 Do you see the error? Does it appear? I don't see it! This is my question. Why doesn't it appear? Commented Aug 11, 2013 at 7:21
  • I grabbed mongodb from npm and concluded that: callbacks are often tested to see if they are of type function, collection.prototype.find() returns Cursor(), Cursor.prototype.toArray does not have an explicit try/catch block around the callback, but that doesn't mean there's not an outer try/catch somewhere. I haven't tried to duplicate your initial problem, so this could be chasing phantoms for all I know. Commented Aug 11, 2013 at 7:57
  • 1
    Upgrade the driver and add an event handler for the "error" event on the db instance to catch any throw exceptions. Also I suggest writing unit/integration tests to catch these issue before actually putting your code into production. agiledata.org/essays/tdd.html Commented Aug 13, 2013 at 13:34

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Can you please detail your answer? Why the error doesn't appear? Which is the reason? Why the process is stopped when calling undefined.something? Can you reproduce the problem in a small Node application? Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.