summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Harter <wavded@gmail.com>2012-06-06 10:17:01 -0500
committerisaacs <i@izs.me>2012-06-08 23:32:13 -0700
commit569acea0eefed2c7da7453b7dcef6ff47491ca1c (patch)
tree3e11e5f797bf434041ab68ac9638485335281a7e
parent4b021a3541770ae64a415760339bdd3223fdf602 (diff)
downloadnode-569acea0eefed2c7da7453b7dcef6ff47491ca1c.tar.gz
Fix #3379 prevent domain.intercept passing 1st arg to cb
-rw-r--r--doc/api/domain.markdown9
-rw-r--r--lib/domain.js28
-rw-r--r--test/simple/test-domain.js7
3 files changed, 41 insertions, 3 deletions
diff --git a/doc/api/domain.markdown b/doc/api/domain.markdown
index 5bbdcc33a..f8df926ab 100644
--- a/doc/api/domain.markdown
+++ b/doc/api/domain.markdown
@@ -227,13 +227,16 @@ with a single error handler in a single place.
var d = domain.create();
function readSomeFile(filename, cb) {
- fs.readFile(filename, d.intercept(function(er, data) {
+ fs.readFile(filename, d.intercept(function(data) {
+ // note, the first argument is never passed to the
+ // callback since it is assumed to be the 'Error' argument
+ // and thus intercepted by the domain.
+
// if this throws, it will also be passed to the domain
- // additionally, we know that 'er' will always be null,
// so the error-handling logic can be moved to the 'error'
// event on the domain instead of being repeated throughout
// the program.
- return cb(er, JSON.parse(data));
+ return cb(null, JSON.parse(data));
}));
}
diff --git a/lib/domain.js b/lib/domain.js
index e865a1faa..12ab409c3 100644
--- a/lib/domain.js
+++ b/lib/domain.js
@@ -167,6 +167,34 @@ Domain.prototype.bind = function(cb, interceptError) {
return;
}
+ // remove first-arg if intercept as assumed to be the error-arg
+ if (interceptError) {
+ var len = arguments.length;
+ var args;
+ switch (len) {
+ case 0:
+ case 1:
+ // no args that we care about.
+ args = [];
+ break;
+ case 2:
+ // optimization for most common case: cb(er, data)
+ args = [arguments[1]];
+ break;
+ default:
+ // slower for less common case: cb(er, foo, bar, baz, ...)
+ args = new Array(len - 1);
+ for (var i = 1; i < len; i++) {
+ args[i] = arguments[i - 1];
+ }
+ break;
+ }
+ self.enter();
+ var ret = cb.apply(this, args);
+ self.exit();
+ return ret;
+ }
+
self.enter();
var ret = cb.apply(this, arguments);
self.exit();
diff --git a/test/simple/test-domain.js b/test/simple/test-domain.js
index e20868ed0..72d7655df 100644
--- a/test/simple/test-domain.js
+++ b/test/simple/test-domain.js
@@ -127,6 +127,13 @@ function fn(er) {
var bound = d.intercept(fn);
bound(new Error('bound'));
+// intercepted should never pass first argument to callback
+function fn2(data) {
+ assert.equal(data, 'data', 'should not be null err argument')
+}
+
+var bound = d.intercept(fn2);
+bound(null, 'data');
// throwing in a bound fn is also caught,