node-odbc icon indicating copy to clipboard operation
node-odbc copied to clipboard

Callbacks from node-odbc lose context

Open Xylem opened this issue 11 years ago • 5 comments

This issue has been tested using node.js 0.10.13 and node-odbc 0.5.23.

This is an issue I encountered when trying to throw exceptions from within node-odbc's callbacks. As it seems, whenever node-odbc executes the callback function, the context is lost, making it impossible to elegantly handle exceptions with domains.

Consider following code:

require("longjohn");

var domain = require("domain");

var d = domain.create();

d.on("error", function (error) {
    console.log("Error caught!");
});

d.run(function() {
    var db = require("odbc")();

    console.trace();

    db.open("wrongConnectionString", function (error) {
        console.trace();

        throw new Error();
    });
});

An expected output would contain two stack traces, with the second one containing the first, and "Error caught!" printed out. However, the actual output is:

Trace
    at /home/vagrant/test-app/index.js:14:13
    at b (domain.js:183:18)
    at Domain.run (domain.js:123:23)
    at Object.<anonymous> (/home/vagrant/test-app/index.js:11:3)
    at Module._compile (module.js:456:26)
    at Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Module._load (module.js:312:12)
    at Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
Trace
    at /home/vagrant/test-app/index.js:17:17
    at /home/vagrant/test-app/node_modules/odbc/lib/odbc.js:88:23

/home/vagrant/test-app/index.js:19
        throw new Error();
              ^
Error
    at /home/vagrant/test-app/index.js:19:15
    at /home/vagrant/test-app/node_modules/odbc/lib/odbc.js:88:23

As can be seen on the second stack trace - everything before callback execution is lost and domain cannot handle the exception. The only way to catch it is to listen to unhandledException event.

This can be compared with such code:

require("longjohn");

var domain = require("domain");

var d = domain.create();

d.on("error", function (error) {
    console.log("Error caught!");
});

d.run(function() {
    console.trace();

    process.nextTick(function () {
        console.trace();

        throw new Error();
    });
});

The code above outputs, as expected:

Trace
    at /home/vagrant/test-app/index.js:12:13
    at b (domain.js:183:18)
    at Domain.run (domain.js:123:23)
    at Object.<anonymous> (/home/vagrant/test-app/index.js:11:3)
    at Module._compile (module.js:456:26)
    at Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Module._load (module.js:312:12)
    at Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
Trace
    at /home/vagrant/test-app/index.js:15:17
    at process._tickDomainCallback (node.js:459:13)
    at Module.runMain (module.js:499:11)
    at startup (node.js:119:16)
    at node.js:901:3
---------------------------------------------
    at /home/vagrant/test-app/index.js:14:13
    at b (domain.js:183:18)
    at Domain.run (domain.js:123:23)
    at Object.<anonymous> (/home/vagrant/test-app/index.js:11:3)
    at Module._compile (module.js:456:26)
    at Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Module._load (module.js:312:12)
Error caught!

Xylem avatar Jul 22 '13 20:07 Xylem

Just out of curiosity, are you using any other compiled modules that work in the manner your are expecting? It would be best for me if I could compare or get some insight on how others have handled this.

wankdanker avatar Jul 22 '13 20:07 wankdanker

Actually, I think I may have spotted the problem. (https://github.com/wankdanker/node-odbc/blob/master/src/odbc_connection.cpp#L266). Looks like the global context is being used. Should be able to get this fixed up in the next couple days.

wankdanker avatar Jul 22 '13 20:07 wankdanker

I stand corrected, looks like there are some special measures which need to be done to call back when using domains as seen in node core. Will see what I can do. But this may take a little bit longer than expected.

wankdanker avatar Jul 22 '13 21:07 wankdanker

Honestly, I would have to check if I have any other compiled modules and if this works the expected way on them. I also forgot to mention that I encountered this initially on a node 0.8 app using node-odbc from npm (0.4.4) if that changes anything. Whatever the outcome, thanks a lot for your involvement!

Xylem avatar Jul 22 '13 21:07 Xylem

Just ran across this same issue running in a domain. Any updates or suggestions.

Trimeego avatar Jul 24 '15 19:07 Trimeego