indapublic
indapublic

Reputation: 2328

Silent exceptions in Q:then callback?

I have some issue with calling function of null variable in 'then' callback of Q.promise.

The first call (without Q using) will show an error, but while the second (wuth Q using) doesn't.

Small example:

var Q = require('q');
var nul = null;
var exp;

(function (exp) {
    var A = (function () {
        function A() {
        };
        A.prototype.foo = function () {
            var d = Q.defer();
            d.resolve('Hello, world');
            return d.promise;
        };
        A.prototype.bar = function (i) {
            switch (i) {
                case 0:
                    /**
                     * That's all ok, "TypeError: Cannot read property 'qqq' of null"
                     */
                    console.log(nul);
                    nul.qqq();
                    console.log('ok');
                    break;
                case 1:
                    /**
                     * it's not ok, I see only result of "console.log(nul)", line 29
                     */
                    this.foo().then(function () {
                        console.log(nul);
                        nul.qqq();
                        console.log('ok');
                    });
                    break;
            };
        };
        return A;
    })();
    exp.A = A;
}) (exp || (exp = {}));

exp.a = new exp.A();
// You should run functions SEPARATELY!!!
exp.a.bar(0);   //  in that case: that's all ok, "TypeError: Cannot read property 'qqq' of null"
exp.a.bar(1);   //  int that case: it's not ok, I see only result of "console.log(nul)", line 29

I don't have any idea how to solve it

Upvotes: 1

Views: 99

Answers (1)

Vale
Vale

Reputation: 2022

The reason why you're not seeing the second error on the console is because Q catches all errors and lets you handle them separately.

You can handle an error in then() by chaining with a catch() function, in your example this can be done this way:

this.foo().then(function () {
    console.log(nul);
    nul.qqq();
    console.log('ok');
}).catch(function(error) {
    // do something with error
    console.log(error);
});

You can get this behavior also by using a try/catch block inside then() like this:

this.foo().then(function () {
    try {
        console.log(nul);
        nul.qqq();
        console.log('ok');
    } catch (e) {
        console.log(e);
    }
});

Old answer

Here are a few options for catching errors in JS/node.js:

Try/Catch blocks

These work like in their Java/C# equivalent, wrap each of the calls you make with a try block and catch an error, handling it in the catch block

try {
    exp.a.bar(0);
} catch(e) {
    console.log(e);
}

You can also add finally blocks, check the type of an exception/error and so on, you can read more about it on the MDN page

Node.js uncaughtException handler

In node, you can catch all uncaught errors, which will stop your program, by binding a callback to the uncaughtException event like this:

process.on('uncaughtException', function (e) {
  console.log('Error: ' + e);
});

This isn't always the best thing to do in a program, but if you really don't want to stop the execution, this is an option.

Finally, I recommend giving a look to this official article for best practices about handling errors in node.js

Upvotes: 1

Related Questions