Repository: DataDog/dd-trace-js
Pull request #5682: Use errorMonitor symbol instead of listening to the error event
Author: login: BridgeAR
Labels: name: semver-patch
Created: 2025-05-08T01:31:07Z | Merged: 2025-05-19T08:46:51Z

This is important to guarantee user code behaves as it did without
the instrumentation. So user crashes should happen as before.


Diff:
diff --git a/packages/datadog-instrumentations/src/child_process.js b/packages/datadog-instrumentations/src/child_process.js
index f722495336..fc8d286d60 100644
--- a/packages/datadog-instrumentations/src/child_process.js
+++ b/packages/datadog-instrumentations/src/child_process.js
@@ -1,5 +1,6 @@
 'use strict'
 
+const { errorMonitor } = require('events')
 const util = require('util')
 
 const {
@@ -227,7 +228,7 @@ function wrapChildProcessAsyncMethod (ChildProcess, shell = false) {
         if (childProcess) {
           let errorExecuted = false
 
-          childProcess.on('error', (e) => {
+          childProcess.on(errorMonitor, (e) => {
             errorExecuted = true
             childProcessChannel.error.publish(e)
           })
diff --git a/packages/datadog-instrumentations/src/couchbase.js b/packages/datadog-instrumentations/src/couchbase.js
index 2cc3083673..311282003f 100644
--- a/packages/datadog-instrumentations/src/couchbase.js
+++ b/packages/datadog-instrumentations/src/couchbase.js
@@ -1,5 +1,6 @@
 'use strict'
 
+const { errorMonitor } = require('events')
 const {
   channel,
   addHook,
@@ -186,7 +187,7 @@ addHook({ name: 'couchbase', file: 'lib/bucket.js', versions: ['^2.6.12'] }, Buc
         finishCh.publish(undefined)
       }))
 
-      emitter.once('error', asyncResource.bind((error) => {
+      emitter.once(errorMonitor, asyncResource.bind((error) => {
         errorCh.publish(error)
         finishCh.publish(undefined)
       }))
diff --git a/packages/datadog-instrumentations/src/fs.js b/packages/datadog-instrumentations/src/fs.js
index c6db494ce5..677c2c4abc 100644
--- a/packages/datadog-instrumentations/src/fs.js
+++ b/packages/datadog-instrumentations/src/fs.js
@@ -1,5 +1,6 @@
 'use strict'
 
+const { errorMonitor } = require('events')
 const { channel, addHook } = require('./helpers/instrument')
 const shimmer = require('../../datadog-shimmer')
 
@@ -199,16 +200,16 @@ function wrapCreateStream (original) {
         }
         const onFinish = () => {
           finishChannel.runStores(ctx, () => {})
-          stream.off('close', onFinish)
-          stream.off('end', onFinish)
-          stream.off('finish', onFinish)
-          stream.off('error', onError)
+          stream.removeListener('close', onFinish)
+          stream.removeListener('end', onFinish)
+          stream.removeListener('finish', onFinish)
+          stream.removeListener(errorMonitor, onError)
         }
 
         stream.once('close', onFinish)
         stream.once('end', onFinish)
         stream.once('finish', onFinish)
-        stream.once('error', onError)
+        stream.once(errorMonitor, onError)
 
         return stream
       } catch (error) {
diff --git a/packages/datadog-instrumentations/src/http/client.js b/packages/datadog-instrumentations/src/http/client.js
index 5afa47e552..244e929b44 100644
--- a/packages/datadog-instrumentations/src/http/client.js
+++ b/packages/datadog-instrumentations/src/http/client.js
@@ -3,6 +3,7 @@
 /* eslint-disable no-fallthrough */
 
 const url = require('url')
+const { errorMonitor } = require('events')
 const { channel, addHook } = require('../helpers/instrument')
 const shimmer = require('../../../datadog-shimmer')
 
@@ -88,7 +89,7 @@ function patch (http, methodName) {
                 const res = arg
                 ctx.res = res
                 res.on('end', finish)
-                res.on('error', finish)
+                res.on(errorMonitor, finish)
                 break
               }
               case 'connect':
diff --git a/packages/datadog-instrumentations/src/mysql2.js b/packages/datadog-instrumentations/src/mysql2.js
index bf7cd2dbcd..ef0e5d43db 100644
--- a/packages/datadog-instrumentations/src/mysql2.js
+++ b/packages/datadog-instrumentations/src/mysql2.js
@@ -1,5 +1,7 @@
 'use strict'
 
+const { errorMonitor } = require('node:events')
+
 const {
   channel,
   addHook,
@@ -138,7 +140,7 @@ function wrapConnection (Connection, version) {
           onResult.apply(this, arguments)
         }, 'bound-anonymous-fn', this))
       } else {
-        this.on('error', asyncResource.bind(error => errorCh.publish(error)))
+        this.on(errorMonitor, asyncResource.bind(error => errorCh.publish(error)))
         this.on('end', asyncResource.bind(() => finishCh.publish(undefined)))
       }
 
diff --git a/packages/datadog-instrumentations/src/net.js b/packages/datadog-instrumentations/src/net.js
index 7059342ada..2e631626c1 100644
--- a/packages/datadog-instrumentations/src/net.js
+++ b/packages/datadog-instrumentations/src/net.js
@@ -1,5 +1,7 @@
 'use strict'
 
+const { errorMonitor } = require('events')
+
 const { channel, addHook } = require('./helpers/instrument')
 const shimmer = require('../../datadog-shimmer')
 
@@ -99,7 +101,7 @@ function getOptions (args) {
 }
 
 function setupListeners (socket, protocol, ctx, finishCh, errorCh) {
-  const events = ['connect', 'error', 'close', 'timeout']
+  const events = ['connect', errorMonitor, 'close', 'timeout']
 
   const wrapListener = function (error) {
     if (error) {
diff --git a/packages/datadog-instrumentations/src/pg.js b/packages/datadog-instrumentations/src/pg.js
index f2dcfeeff1..fa92ea0b84 100644
--- a/packages/datadog-instrumentations/src/pg.js
+++ b/packages/datadog-instrumentations/src/pg.js
@@ -129,21 +129,15 @@ function wrapQuery (query) {
         }
       } else if (newQuery.once) {
         newQuery
-          .once('error', finish)
+          .once(errorMonitor, finish)
           .once('end', (res) => finish(null, res))
       } else {
+        // TODO: This code is never reached in our tests.
+        // Internally, pg always uses callbacks or streams, even for promise based queries.
+        // Investigate if this code should just be removed.
         newQuery.then((res) => finish(null, res), finish)
       }
 
-      if (stream) {
-        newQuery.on('end', () => {
-          finish(null, [])
-        })
-        newQuery.on(errorMonitor, (err) => {
-          finish(err)
-        })
-      }
-
       try {
         return retval
       } catch (err) {
diff --git a/packages/datadog-instrumentations/test/child_process.spec.js b/packages/datadog-instrumentations/test/child_process.spec.js
index f6d1942379..2b03db321b 100644
--- a/packages/datadog-instrumentations/test/child_process.spec.js
+++ b/packages/datadog-instrumentations/test/child_process.spec.js
@@ -102,6 +102,10 @@ describe('child process', () => {
               it('should execute error callback', (done) => {
                 const childEmitter = childProcess[methodName]('invalid_command_test')
 
+                expect(childEmitter.listenerCount('error')).to.equal(methodName.includes('spawn') ? 0 : 1)
+
+                childEmitter.once('error', () => {})
+
                 childEmitter.once('close', () => {
                   expect(start).to.have.been.calledOnceWith({
                     command: 'invalid_command_test',
diff --git a/packages/datadog-instrumentations/test/mysql2.spec.js b/packages/datadog-instrumentations/test/mysql2.spec.js
index 89e35f2a1f..dce3fb183c 100644
--- a/packages/datadog-instrumentations/test/mysql2.spec.js
+++ b/packages/datadog-instrumentations/test/mysql2.spec.js
@@ -4,6 +4,7 @@ const { channel } = require('../src/helpers/instrument')
 const agent = require('../../dd-trace/test/plugins/agent')
 const { assert } = require('chai')
 const semver = require('semver')
+const { once } = require('events')
 
 describe('mysql2 instrumentation', () => {
   withVersions('mysql2', 'mysql2', version => {
@@ -435,16 +436,17 @@ describe('mysql2 instrumentation', () => {
               query.on('end', () => done())
             })
 
-            it('should work without abortController.abort()', (done) => {
+            it('should work without abortController.abort()', async () => {
               startCh.subscribe(noop)
               const query = pool.query(sql)
 
-              query.on('error', err => done(err))
-              query.on('end', () => {
-                sinon.assert.called(apmQueryStart)
+              expect(query.listenerCount('error')).to.equal(0)
 
-                done()
-              })
+              await once(query, 'end')
+
+              expect(query.listenerCount('error')).to.equal(0)
+
+              sinon.assert.called(apmQueryStart)
             })
 
             it('should work without subscriptions', (done) => {
diff --git a/packages/datadog-plugin-fs/test/index.spec.js b/packages/datadog-plugin-fs/test/index.spec.js
index a341e31fc7..7e96bedc73 100644
--- a/packages/datadog-plugin-fs/test/index.spec.js
+++ b/packages/datadog-plugin-fs/test/index.spec.js
@@ -675,7 +675,10 @@ describe('Plugin', () => {
               'file.flag': 'r'
             }
           })
-          fs.createReadStream(__filename).on('error', done).resume()
+          const stream = fs.createReadStream(__filename)
+          expect(stream.listenerCount('error')).to.equal(0)
+
+          stream.on('error', done).resume()
         })
 
         it('should be instrumented when closed', (done) => {
diff --git a/packages/datadog-plugin-http/test/client.spec.js b/packages/datadog-plugin-http/test/client.spec.js
index 6af6011b87..4b632aaf58 100644
--- a/packages/datadog-plugin-http/test/client.spec.js
+++ b/packages/datadog-plugin-http/test/client.spec.js
@@ -414,6 +414,7 @@ describe('Plugin', () => {
           appListener = server(app, port => {
             const req = http.request(`${protocol}://localhost:${port}/user`, res => {
               setTimeout(() => {
+                expect(res.listenerCount('error')).to.equal(0)
                 res.on('data', () => done())
               })
             })
diff --git a/packages/datadog-plugin-net/test/index.spec.js b/packages/datadog-plugin-net/test/index.spec.js
index b3fc60ece3..153f1f5af2 100644
--- a/packages/datadog-plugin-net/test/index.spec.js
+++ b/packages/datadog-plugin-net/test/index.spec.js
@@ -69,7 +69,8 @@ describe('Plugin', () => {
         }).then(done).catch(done)
 
         tracer.scope().activate(parent, () => {
-          net.connect('/tmp/dd-trace.sock')
+          const socket = net.connect('/tmp/dd-trace.sock')
+          expect(socket.listenerCount('error')).to.equal(0)
         })
       })
 
@@ -84,6 +85,7 @@ describe('Plugin', () => {
               resource: 'localhost'
             }, 2000).then(done).catch(done)
           })
+          expect(socket.listenerCount('error')).to.equal(0)
         })
       })
 
@@ -123,6 +125,7 @@ describe('Plugin', () => {
               parent_id: BigInt(parent.context()._spanId.toString(10))
             }, 2000).then(done).catch(done)
           })
+          expect(socket.listenerCount('error')).to.equal(0)
         })
       })
 
diff --git a/packages/datadog-plugin-pg/test/index.spec.js b/packages/datadog-plugin-pg/test/index.spec.js
index ac4a142c9f..096084e81b 100644
--- a/packages/datadog-plugin-pg/test/index.spec.js
+++ b/packages/datadog-plugin-pg/test/index.spec.js
@@ -1,6 +1,7 @@
 'use strict'
 
 const { expect } = require('chai')
+const assert = require('assert')
 const semver = require('semver')
 const agent = require('../../dd-trace/test/plugins/agent')
 const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../dd-trace/src/constants')
@@ -263,6 +264,7 @@ describe('Plugin', () => {
                     expect(traces[0][0]).to.have.property('service', expectedSchema.outbound.serviceName)
                     expect(traces[0][0]).to.have.property('resource', 'SELECT * FROM generate_series(0, 1) num')
                     expect(traces[0][0]).to.have.property('type', 'sql')
+                    expect(traces[0][0]).to.have.property('error', 0)
                     expect(traces[0][0].meta).to.have.property('span.kind', 'client')
                     expect(traces[0][0].meta).to.have.property('db.name', 'postgres')
                     expect(traces[0][0].meta).to.have.property('db.type', 'postgres')
@@ -274,11 +276,48 @@ describe('Plugin', () => {
                   const query = new QueryStream('SELECT * FROM generate_series(0, 1) num', [])
                   const stream = client.query(query)
 
-                  for await (const row of stream) {
-                    expect(row).to.have.property('num')
-                  }
+                  expect(stream.listenerCount('error')).to.equal(0)
 
-                  await agentPromise
+                  const readPromise = (async () => {
+                    for await (const row of stream) {
+                      expect(row).to.have.property('num')
+                    }
+                  })()
+
+                  await Promise.all([readPromise, agentPromise])
+                })
+
+                it('should instrument stream-based queries with pg-query-stream and catch errors', async () => {
+                  const agentPromise = agent.use(traces => {
+                    expect(traces[0][0]).to.have.property('name', expectedSchema.outbound.opName)
+                    expect(traces[0][0]).to.have.property('service', expectedSchema.outbound.serviceName)
+                    expect(traces[0][0]).to.have.property('resource', 'SELECT * FROM generate_series(0, 1) num')
+                    expect(traces[0][0]).to.have.property('type', 'sql')
+                    expect(traces[0][0]).to.have.property('error', 1)
+                    expect(traces[0][0].meta).to.have.property('span.kind', 'client')
+                    expect(traces[0][0].meta).to.have.property('db.name', 'postgres')
+                    expect(traces[0][0].meta).to.have.property('db.type', 'postgres')
+                    expect(traces[0][0].meta).to.have.property('component', 'pg')
+                    expect(traces[0][0].metrics).to.have.property('db.stream', 1)
+                    expect(traces[0][0].metrics).to.have.property('network.destination.port', 5432)
+                  })
+
+                  const query = new QueryStream('SELECT * FROM generate_series(0, 1) num', [])
+                  const stream = client.query(query)
+
+                  expect(stream.listenerCount('error')).to.equal(0)
+
+                  const rejectedRead = assert.rejects(async () => {
+                    // eslint-disable-next-line no-unreachable-loop
+                    for await (const row of stream) {
+                      expect(row).to.have.property('num')
+                      throw new Error('Test error')
+                    }
+                  }, {
+                    message: 'Test error'
+                  })
+
+                  await Promise.all([rejectedRead, agentPromise])
                 })
               })
             })


Reviews:
user: login: BridgeAR
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T23:03:35Z
user: login: watson
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-15T05:07:41Z
user: login: BridgeAR
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T10:18:58Z
user: login: BridgeAR
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T10:23:58Z
user: login: BridgeAR
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T10:27:02Z
user: login: watson
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-16T07:34:22Z
user: login: watson
body: Looks good. Just my one nit about the TODO comment. Feel free to merge without it or add it and I'll re-approve
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-05-16T07:38:59Z
user: login: watson
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-19T08:45:59Z

Review comments:
diff_hunk: @@ -129,21 +129,12 @@ function wrapQuery (query) {
         }
       } else if (newQuery.once) {
         newQuery
-          .once('error', finish)
+          .once(errorMonitor, finish)
           .once('end', (res) => finish(null, res))
       } else {
         newQuery.then((res) => finish(null, res), finish)
       }
 
-      if (stream) {
-        newQuery.on('end', () => {
-          finish(null, [])
-        })
-        newQuery.on(errorMonitor, (err) => {
-          finish(err)
-        })
-      }
-
path: packages/datadog-instrumentations/src/pg.js
user: login: BridgeAR
body: This was actually adding a second listener. Now, it's only a single one and only the monitor one.
created_at: 2025-05-14T23:03:34Z
author_association: MEMBER
diff_hunk: @@ -1,5 +1,6 @@
 'use strict'
 
+const { errorMonitor } = require('events')
path: packages/datadog-instrumentations/src/couchbase.js
user: login: watson
body: Nit: You sometimes use `events` and sometimes `node:events`. Feel free to ignore me

```suggestion
const { errorMonitor } = require('node:events')
```
created_at: 2025-05-15T04:53:08Z
author_association: COLLABORATOR
diff_hunk: @@ -129,21 +129,12 @@ function wrapQuery (query) {
         }
       } else if (newQuery.once) {
         newQuery
-          .once('error', finish)
+          .once(errorMonitor, finish)
           .once('end', (res) => finish(null, res))
       } else {
         newQuery.then((res) => finish(null, res), finish)
       }
 
-      if (stream) {
-        newQuery.on('end', () => {
-          finish(null, [])
-        })
-        newQuery.on(errorMonitor, (err) => {
-          finish(err)
-        })
-      }
-
path: packages/datadog-instrumentations/src/pg.js
user: login: watson
body: Well, it wasn't adding a second listener in case `newQuery.callback` is truthy. In that case it's the only one. However, one would assume that the callback override above should serve the same purpose, so I agree with you that removing of this if-statement seems like the right move. Have you verified that this code is covered by tests?
created_at: 2025-05-15T04:58:41Z
author_association: COLLABORATOR
diff_hunk: @@ -435,16 +436,18 @@ describe('mysql2 instrumentation', () => {
               query.on('end', () => done())
             })
 
-            it('should work without abortController.abort()', (done) => {
+            it('should work without abortController.abort()', async () => {
               startCh.subscribe(noop)
               const query = pool.query(sql)
 
-              query.on('error', err => done(err))
-              query.on('end', () => {
-                sinon.assert.called(apmQueryStart)
+              let error
+              query.on('error', err => { error = err })
+              expect(query.listenerCount('error')).to.equal(1)
 
-                done()
-              })
+              await once(query, 'end')
+              expect(query.listenerCount('error')).to.equal(1)
+              sinon.assert.called(apmQueryStart)
+              expect(error).to.be.undefined
path: packages/datadog-instrumentations/test/mysql2.spec.js
user: login: watson
body: This check, and the `error` listener you add above shouldn't be necessary, as the `await once(query, 'end')` will be rejected if `query` emits and error, and hence the test will fail and never reach this point.
created_at: 2025-05-15T05:06:50Z
author_association: COLLABORATOR
diff_hunk: @@ -129,21 +129,12 @@ function wrapQuery (query) {
         }
       } else if (newQuery.once) {
         newQuery
-          .once('error', finish)
+          .once(errorMonitor, finish)
           .once('end', (res) => finish(null, res))
       } else {
         newQuery.then((res) => finish(null, res), finish)
       }
 
-      if (stream) {
-        newQuery.on('end', () => {
-          finish(null, [])
-        })
-        newQuery.on(errorMonitor, (err) => {
-          finish(err)
-        })
-      }
-
path: packages/datadog-instrumentations/src/pg.js
user: login: BridgeAR
body: The time this was added, tests were added that would fail if the above listener is removed. All callback cases are event emitters but it's fine, since we wait for that to finish. It was only important if there was no callback.

I did however do a closer check and added a test for failing cases as well.
Interestingly, the .then part is never going to be reached in any of our cases, even the promise related tests. The pg internals just all work with callbacks. I wonder if we want to remove that condition.
created_at: 2025-05-15T10:18:58Z
author_association: MEMBER
diff_hunk: @@ -435,16 +436,18 @@ describe('mysql2 instrumentation', () => {
               query.on('end', () => done())
             })
 
-            it('should work without abortController.abort()', (done) => {
+            it('should work without abortController.abort()', async () => {
               startCh.subscribe(noop)
               const query = pool.query(sql)
 
-              query.on('error', err => done(err))
-              query.on('end', () => {
-                sinon.assert.called(apmQueryStart)
+              let error
+              query.on('error', err => { error = err })
+              expect(query.listenerCount('error')).to.equal(1)
 
-                done()
-              })
+              await once(query, 'end')
+              expect(query.listenerCount('error')).to.equal(1)
+              sinon.assert.called(apmQueryStart)
+              expect(error).to.be.undefined
path: packages/datadog-instrumentations/test/mysql2.spec.js
user: login: BridgeAR
body: True, while it likely depends on the Node.js version to prevent an error from being emitted after 'end'. I'll simplify it.
created_at: 2025-05-15T10:23:58Z
author_association: MEMBER
diff_hunk: @@ -1,5 +1,6 @@
 'use strict'
 
+const { errorMonitor } = require('events')
path: packages/datadog-instrumentations/src/couchbase.js
user: login: BridgeAR
body: Yeah... I am a bit indecisive to use them.
I'll keep it for now due to otherwise running an extra CI and I don't think it should matter overall.
created_at: 2025-05-15T10:27:01Z
author_association: MEMBER
diff_hunk: @@ -129,21 +129,12 @@ function wrapQuery (query) {
         }
       } else if (newQuery.once) {
         newQuery
-          .once('error', finish)
+          .once(errorMonitor, finish)
           .once('end', (res) => finish(null, res))
       } else {
         newQuery.then((res) => finish(null, res), finish)
       }
 
-      if (stream) {
-        newQuery.on('end', () => {
-          finish(null, [])
-        })
-        newQuery.on(errorMonitor, (err) => {
-          finish(err)
-        })
-      }
-
path: packages/datadog-instrumentations/src/pg.js
user: login: watson
body: I think for now leave it as is, as it's a bit outside the scope of this PR. Maybe just add a TODO comment?
created_at: 2025-05-16T07:34:22Z
author_association: COLLABORATOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-08T01:32:06Z
body: 
# Overall package size

Self size: 9.38 MB
Deduped: 103.4 MB
No deduping: 103.92 MB

<details><summary>Dependency sizes</summary>
| name | version | self size | total size |
|------|---------|-----------|------------|
| @datadog/libdatadog | 0.5.1 | 29.73 MB | 29.73 MB |
| @datadog/native-appsec | 8.5.2 | 19.33 MB | 19.34 MB |
| @datadog/pprof | 5.8.0 | 12.55 MB | 12.92 MB |
| @datadog/native-iast-taint-tracking | 4.0.0 | 11.72 MB | 11.73 MB |
| @opentelemetry/core | 1.30.1 | 908.66 kB | 7.16 MB |
| protobufjs | 7.4.0 | 2.77 MB | 5.42 MB |
| @datadog/wasm-js-rewriter | 4.0.1 | 2.85 MB | 3.58 MB |
| @datadog/native-metrics | 3.1.1 | 1.02 MB | 1.43 MB |
| @opentelemetry/api | 1.8.0 | 1.21 MB | 1.21 MB |
| import-in-the-middle | 1.13.1 | 117.64 kB | 839.26 kB |
| source-map | 0.7.4 | 226 kB | 226 kB |
| opentracing | 0.14.7 | 194.81 kB | 194.81 kB |
| lru-cache | 7.18.3 | 133.92 kB | 133.92 kB |
| pprof-format | 2.1.0 | 111.69 kB | 111.69 kB |
| @datadog/sketches-js | 2.1.1 | 109.9 kB | 109.9 kB |
| lodash.sortby | 4.7.0 | 75.76 kB | 75.76 kB |
| ignore | 5.3.2 | 53.63 kB | 53.63 kB |
| istanbul-lib-coverage | 3.2.0 | 29.34 kB | 29.34 kB |
| rfdc | 1.4.1 | 27.15 kB | 27.15 kB |
| @isaacs/ttlcache | 1.4.1 | 25.2 kB | 25.2 kB |
| dc-polyfill | 0.1.8 | 25.08 kB | 25.08 kB |
| tlhunter-sorted-set | 0.1.0 | 24.94 kB | 24.94 kB |
| shell-quote | 1.8.2 | 23.54 kB | 23.54 kB |
| limiter | 1.1.5 | 23.17 kB | 23.17 kB |
| retry | 0.13.1 | 18.85 kB | 18.85 kB |
| semifies | 1.0.0 | 15.84 kB | 15.84 kB |
| jest-docblock | 29.7.0 | 8.99 kB | 12.76 kB |
| crypto-randomuuid | 1.0.0 | 11.18 kB | 11.18 kB |
| ttl-set | 1.0.0 | 4.61 kB | 9.69 kB |
| mutexify | 1.4.0 | 5.71 kB | 8.74 kB |
| path-to-regexp | 0.1.12 | 6.6 kB | 6.6 kB |
| koalas | 1.0.2 | 6.47 kB | 6.47 kB |
| module-details-from-path | 1.0.3 | 4.47 kB | 4.47 kB |


</details>



<sub>🤖 This report was automatically generated by [heaviest-objects-in-the-universe](https://github.com/qard/heaviest-objects-in-the-universe/)<sub>
author_association: CONTRIBUTOR
user: login: codecov[bot]
created_at: 2025-05-08T01:32:28Z
body: ## [Codecov](https://app.codecov.io/gh/DataDog/dd-trace-js/pull/5682?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) Report
Attention: Patch coverage is `87.50000%` with `2 lines` in your changes missing coverage. Please review.
> Project coverage is 79.05%. Comparing base [(`3a2ed10`)](https://app.codecov.io/gh/DataDog/dd-trace-js/commit/3a2ed100ebf7c787bc86340e619eb6c9229797cb?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) to head [(`458e049`)](https://app.codecov.io/gh/DataDog/dd-trace-js/commit/458e04917c23d036974e98fee4f44c4c4e1d7de8?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog).
> Report is 9 commits behind head on master.

| [Files with missing lines](https://app.codecov.io/gh/DataDog/dd-trace-js/pull/5682?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) | Patch % | Lines |
|---|---|---|
| [...ckages/datadog-instrumentations/src/http/client.js](https://app.codecov.io/gh/DataDog/dd-trace-js/pull/5682?src=pr&el=tree&filepath=packages%2Fdatadog-instrumentations%2Fsrc%2Fhttp%2Fclient.js&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog#diff-cGFja2FnZXMvZGF0YWRvZy1pbnN0cnVtZW50YXRpb25zL3NyYy9odHRwL2NsaWVudC5qcw==) | 50.00% | [1 Missing :warning: ](https://app.codecov.io/gh/DataDog/dd-trace-js/pull/5682?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) |
| [packages/datadog-instrumentations/src/net.js](https://app.codecov.io/gh/DataDog/dd-trace-js/pull/5682?src=pr&el=tree&filepath=packages%2Fdatadog-instrumentations%2Fsrc%2Fnet.js&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog#diff-cGFja2FnZXMvZGF0YWRvZy1pbnN0cnVtZW50YXRpb25zL3NyYy9uZXQuanM=) | 50.00% | [1 Missing :warning: ](https://app.codecov.io/gh/DataDog/dd-trace-js/pull/5682?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) |

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master    #5682   +/-   ##
=======================================
  Coverage   79.04%   79.05%           
=======================================
  Files         515      515           
  Lines       23589    23590    +1     
=======================================
+ Hits        18647    18648    +1     
  Misses       4942     4942           
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/DataDog/dd-trace-js/pull/5682?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: datadog-datadog-prod-us1[bot]
created_at: 2025-05-08T01:39:27Z
body: 
## Datadog Report

Branch report: [`BridgeAR/safer-on-error`](https://app.datadoghq.com/ci/test-branch/github.com%2Fdatadog%2Fdd-trace-js/dd-trace-js-integration-tests/BridgeAR%2Fsafer-on-error?env=none&index=citest&_user_click_origin_=github)
Commit report: [`f886e1e`](https://app.datadoghq.com/ci/test-commit/github.com%2Fdatadog%2Fdd-trace-js/dd-trace-js-integration-tests/BridgeAR%2Fsafer-on-error/f886e1e78bb9fc97c6741e93cf2c97296f9d4d1e?env=none&index=citest&_user_click_origin_=github)
Test service: `dd-trace-js-integration-tests`

:white_check_mark: 0 Failed, 985 Passed, 0 Skipped, 14m 54.77s Total Time




author_association: NONE
user: login: pr-commenter[bot]
created_at: 2025-05-08T01:40:39Z
body: ## Benchmarks

Benchmark execution time: 2025-05-18 18:49:35

Comparing candidate commit 458e04917c23d036974e98fee4f44c4c4e1d7de8 in PR branch `BridgeAR/safer-on-error` with baseline commit 3a2ed100ebf7c787bc86340e619eb6c9229797cb in branch `master`.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 1268 metrics, 55 unstable metrics.


author_association: NONE