From 621f423d23e684108fb3d3224f7974c2a1291e2a Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Mon, 28 Mar 2022 17:32:14 -0400 Subject: [PATCH] fix `AsyncResource.bind()` binding `this` to itself by default (#1942) --- .../src/helpers/instrument.js | 21 ++++++++++++++----- .../datadog-plugin-net/test/index.spec.js | 3 ++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/datadog-instrumentations/src/helpers/instrument.js b/packages/datadog-instrumentations/src/helpers/instrument.js index 9108087acea..6689e9d8dd9 100644 --- a/packages/datadog-instrumentations/src/helpers/instrument.js +++ b/packages/datadog-instrumentations/src/helpers/instrument.js @@ -88,7 +88,9 @@ function getBasedir (id) { return parse(id).basedir.replace(pathSepExpr, '/') } -if (semver.satisfies(process.versions.node, '>=16.0.0')) { +// AsyncResource.bind exists and binds `this` properly only from 17.8.0 and up. +// https://nodejs.org/api/async_context.html#asyncresourcebindfn-thisarg +if (semver.satisfies(process.versions.node, '>=17.8.0')) { exports.AsyncResource = AsyncResource } else { exports.AsyncResource = class extends AsyncResource { @@ -97,9 +99,18 @@ if (semver.satisfies(process.versions.node, '>=16.0.0')) { return (new exports.AsyncResource(type || 'bound-anonymous-fn')).bind(fn, thisArg) } - bind (fn, thisArg = this) { - const ret = this.runInAsyncScope.bind(this, fn, thisArg) - Object.defineProperties(ret, { + bind (fn, thisArg) { + let bound + if (thisArg === undefined) { + const resource = this + bound = function (...args) { + args.unshift(fn, this) + return Reflect.apply(resource.runInAsyncScope, resource, args) + } + } else { + bound = this.runInAsyncScope.bind(this, fn, thisArg) + } + Object.defineProperties(bound, { 'length': { configurable: true, enumerable: false, @@ -113,7 +124,7 @@ if (semver.satisfies(process.versions.node, '>=16.0.0')) { writable: true } }) - return ret + return bound } } } diff --git a/packages/datadog-plugin-net/test/index.spec.js b/packages/datadog-plugin-net/test/index.spec.js index e23570d2c25..886101ad461 100644 --- a/packages/datadog-plugin-net/test/index.spec.js +++ b/packages/datadog-plugin-net/test/index.spec.js @@ -220,7 +220,8 @@ describe('Plugin', () => { const socket = new net.Socket() tracer.scope().activate(parent, () => { - socket.connect({ port }, () => { + socket.connect({ port }, function () { + expect(this).to.equal(socket) expect(tracer.scope().active()).to.equal(parent) socket.destroy() done()