node-odbc
node-odbc copied to clipboard
Callbacks from node-odbc lose context
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!
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.
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.
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.
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!
Just ran across this same issue running in a domain. Any updates or suggestions.