Skip to content
Merged
Changes from 1 commit
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
40 changes: 40 additions & 0 deletions packages/dd-trace/test/setup/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@
return originalAdd(warning)
}

// Suppress Node's HTTP keep-alive `socketErrorListener` leak (introduced by
// https://github.com/nodejs/node/pull/61770; fix at
// https://github.com/nodejs/node/pull/62872 not yet released in v24.x). Bump
// the leaking socket's limit and drop the warning before stderr or the
// `'warning'` event sees it, so real leaks still throw below.
const originalEmitWarning = process.emitWarning
process.emitWarning = function patchedEmitWarning (warning, ...args) {
if (
typeof warning === 'object' &&

Check failure on line 77 in packages/dd-trace/test/setup/core.js

View workflow job for this annotation

GitHub Actions / lint

"typeof warning === 'object'" missing not-null guard
warning?.name === 'MaxListenersExceededWarning' &&
isNodeHttpSocketLeak(warning)
) {
warning.emitter.setMaxListeners(0)
Comment thread
BridgeAR marked this conversation as resolved.
return
}
return originalEmitWarning.call(this, warning, ...args)
}

process.on('warning', (warning) => {
if (warning.name === 'MaxListenersExceededWarning') {
throw warning
Expand All @@ -84,6 +102,28 @@
}
})

/**
* Detect the Node.js HTTP keep-alive socket error listener leak by its only
* stable signature: two or more listeners named `socketErrorListener` on the
* same emitter for event `error`. Once the upstream fix ships the duplicates
* disappear and this returns false again, so real leaks resume throwing.
*
* @param {Error & { emitter?: NodeJS.EventEmitter, type?: string }} warning
* @returns {boolean}
*/
function isNodeHttpSocketLeak (warning) {
if (warning.type !== 'error' || typeof warning.emitter?.listeners !== 'function') {
return false
}
let count = 0
for (const listener of warning.emitter.listeners('error')) {
if (listener.name === 'socketErrorListener' && ++count > 1) {
return true
}
}
return false
}

// Make this file a module for type-aware tooling. It is intentionally imported
// for side effects only.
module.exports = {
Expand Down
Loading