Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ function traceInstanceMethod (state, node, program) {

// If the method exists on the class, we return as it will be patched later
// while traversing child nodes later on.
if (classBody.body.some(({ key }) => key.name === methodName)) return
// `key` is absent on members without one (e.g. ES2022 `static {}` blocks),
// so guard against reading `.name` on undefined.
if (classBody.body.some(({ key }) => key?.name === methodName)) return

// Method doesn't exist on the class so we assume an instance method and
// wrap it in the constructor instead.
Expand Down
18 changes: 18 additions & 0 deletions tests/static_block_cjs/mod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
* This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2025 Datadog, Inc.
**/
class UndiciBase {
async fetch (url) {
return 42
}
}
class Undici extends UndiciBase {
static { this.KIND = 'undici' }
static { this.VERSION = 1 }
async fetch (url) {
return super.fetch(url)
}
}

module.exports = Undici
21 changes: 21 additions & 0 deletions tests/static_block_cjs/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
* This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2025 Datadog, Inc.
**/
const Undici = require('./instrumented.js')
const { assert, getContext } = require('../common/preamble.js')
const context = getContext('orchestrion:undici:Undici:fetch');
(async () => {
// Static init blocks are preserved and still run.
assert.strictEqual(Undici.KIND, 'undici')
assert.strictEqual(Undici.VERSION, 1)
const undici = new Undici()
const result = await undici.fetch('https://example.com')
assert.strictEqual(result, 42)
assert.deepStrictEqual(context, {
start: true,
end: true,
asyncStart: 42,
asyncEnd: 42
})
})()
12 changes: 12 additions & 0 deletions tests/tests.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ describe('class_method_cjs', () => {
})
})

describe('static_block_cjs', () => {
test('instruments class method when class body has static init blocks', () => {
runTest('static_block_cjs', [
{
channelName: 'Undici:fetch',
module: { name: TEST_MODULE_NAME, versionRange: '>=0.0.1', filePath: TEST_MODULE_PATH },
functionQuery: { className: 'Undici', methodName: 'fetch', kind: 'Async' },
},
])
})
})

describe('constructor_cjs', () => {
test('instruments class constructor (cjs)', () => {
runTest('constructor_cjs', [
Expand Down
Loading