newrelic 13.6.4 → 13.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/NEWS.md CHANGED
@@ -1,11 +1,26 @@
1
- ### v13.6.4 (2025-11-13)
2
-
3
- #### Bug fixes
4
-
5
- * Updated `MessageConsumerSubscriber` to end transaction created for a given message consumption ([#3503](https://github.com/newrelic/node-newrelic/pull/3503)) ([ba30818](https://github.com/newrelic/node-newrelic/commit/ba308184e5cb4f916aec53963cce0caa9149efbe))
6
- * Updated `MessageProducerSubscriber` to properly set the sampled flag on `traceparent` ([#3505](https://github.com/newrelic/node-newrelic/pull/3505)) ([0b1a9a8](https://github.com/newrelic/node-newrelic/commit/0b1a9a80b81e0f4388d421f17176eab386d04cbc))
7
- * Updated the bedrock middleware to be registered with a `high` priority to ensure payload is properly deserialized ([#3500](https://github.com/newrelic/node-newrelic/pull/3500)) ([63e531b](https://github.com/newrelic/node-newrelic/commit/63e531bf50d600d92556b3785725dd38145f3491))
8
-
1
+ ### v13.6.5 (2025-11-17)
2
+
3
+ #### Bug fixes
4
+
5
+ * Updated express instrumentation to ignore error when the `next` handler passes `route` or `router` ([#3513](https://github.com/newrelic/node-newrelic/pull/3513)) ([724b218](https://github.com/newrelic/node-newrelic/commit/724b218174bddcf2ecf8cffc317bbfad1f0012eb))
6
+ * Updated MessageConsumerSubscriber to wait for consumer callback to end when it is a promise ([#3510](https://github.com/newrelic/node-newrelic/pull/3510)) ([45667a0](https://github.com/newrelic/node-newrelic/commit/45667a0ce2aaaf57a5e7a8acc8f0feea31e6152f))
7
+
8
+ #### Documentation
9
+
10
+ * Updated compatibility report ([#3498](https://github.com/newrelic/node-newrelic/pull/3498)) ([ef41b38](https://github.com/newrelic/node-newrelic/commit/ef41b3851b2096035d5b7b655d5243a9aeb699c8))
11
+
12
+ #### Tests
13
+
14
+ * Updated aws sdk v3 s3 test to no longer test DeleteBucketCommand ([#3512](https://github.com/newrelic/node-newrelic/pull/3512)) ([df27448](https://github.com/newrelic/node-newrelic/commit/df274484e0e657fd9c38452e500450878fc24ee4))
15
+
16
+ ### v13.6.4 (2025-11-13)
17
+
18
+ #### Bug fixes
19
+
20
+ * Updated `MessageConsumerSubscriber` to end transaction created for a given message consumption ([#3503](https://github.com/newrelic/node-newrelic/pull/3503)) ([ba30818](https://github.com/newrelic/node-newrelic/commit/ba308184e5cb4f916aec53963cce0caa9149efbe))
21
+ * Updated `MessageProducerSubscriber` to properly set the sampled flag on `traceparent` ([#3505](https://github.com/newrelic/node-newrelic/pull/3505)) ([0b1a9a8](https://github.com/newrelic/node-newrelic/commit/0b1a9a80b81e0f4388d421f17176eab386d04cbc))
22
+ * Updated the bedrock middleware to be registered with a `high` priority to ensure payload is properly deserialized ([#3500](https://github.com/newrelic/node-newrelic/pull/3500)) ([63e531b](https://github.com/newrelic/node-newrelic/commit/63e531bf50d600d92556b3785725dd38145f3491))
23
+
9
24
  ### v13.6.3 (2025-11-11)
10
25
 
11
26
  #### Bug fixes
@@ -8048,3 +8063,4 @@ Special thanks to Ryan Copley (@RyanCopley) for the contribution.
8048
8063
 
8049
8064
 
8050
8065
 
8066
+
@@ -9,8 +9,11 @@ const isString = require('#agentlib/util/is-string.js')
9
9
 
10
10
  /**
11
11
  * This subscriber is two-fold:
12
- * 1. capture the connection arguments and assign to symbol on connection to be used for all other amqplib subscribers
13
- * 2. create a segment for the connect. Not this will attempt to create a segment but the base subscriber will decide if it is created or not, otherwise it'll return the current context
12
+ * 1. Capture the connection arguments and assign to symbol on connection to be
13
+ * used for all other amqplib subscribers.
14
+ * 2. Create a segment for the connect. Note this will attempt to create a segment
15
+ * but the base subscriber will decide if it is created or not, otherwise it'll
16
+ * return the current context.
14
17
  */
15
18
  class ConnectSubscriber extends Subscriber {
16
19
  constructor({ agent, logger }) {
@@ -114,7 +114,9 @@ class Subscriber {
114
114
  asyncStart.runStores(context, () => {
115
115
  try {
116
116
  if (callback) {
117
- return Reflect.apply(callback, this, arguments)
117
+ const cbResult = Reflect.apply(callback, this, arguments)
118
+ context.cbResult = cbResult
119
+ return cbResult
118
120
  }
119
121
  } finally {
120
122
  asyncEnd.publish(context)
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright 2025 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ const MiddlewareSubscriber = require('../middleware')
7
+
8
+ /**
9
+ * Special error handler to ignore if the error passed to next handler
10
+ * is 'route' or 'router', which are used by Express internally to
11
+ * skip out of a route or router.
12
+ *
13
+ * @param {*} err - The error passed to the next handler
14
+ * @returns {boolean} - returns true if error exists and not equal to a string or `route` or `router`
15
+ */
16
+ function errorHandler(err) {
17
+ return err && err !== 'route' && err !== 'router'
18
+ }
19
+
20
+ class ExpressSubscriber extends MiddlewareSubscriber {
21
+ constructor({ agent, logger, packageName = 'express', channelName }) {
22
+ super({ agent, logger, packageName, channelName, system: 'Expressjs', errorHandler })
23
+ }
24
+ }
25
+
26
+ module.exports = ExpressSubscriber
@@ -5,11 +5,11 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- const MiddlewareSubscriber = require('../middleware')
8
+ const ExpressSubscriber = require('./base')
9
9
 
10
- class ExpressParamSubscriber extends MiddlewareSubscriber {
11
- constructor({ agent, logger, packageName = 'express' }) {
12
- super({ agent, logger, packageName, channelName: 'nr_param', system: 'Expressjs' })
10
+ class ExpressParamSubscriber extends ExpressSubscriber {
11
+ constructor({ agent, logger, packageName }) {
12
+ super({ agent, logger, packageName, channelName: 'nr_param' })
13
13
  }
14
14
 
15
15
  handler(data) {
@@ -5,12 +5,12 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- const MiddlewareSubscriber = require('../middleware')
9
8
  const methods = ['all', 'delete', 'get', 'head', 'post', 'put', 'patch']
9
+ const ExpressSubscriber = require('./base')
10
10
 
11
- class ExpressRouteSubscriber extends MiddlewareSubscriber {
12
- constructor({ agent, logger, packageName = 'express' }) {
13
- super({ agent, logger, packageName, channelName: 'nr_route', system: 'Expressjs' })
11
+ class ExpressRouteSubscriber extends ExpressSubscriber {
12
+ constructor({ agent, logger, packageName }) {
13
+ super({ agent, logger, packageName, channelName: 'nr_route' })
14
14
  this.events = ['end']
15
15
  }
16
16
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- const MiddlewareSubscriber = require('../middleware')
8
+ const ExpressSubscriber = require('./base')
9
9
 
10
- class ExpressUseSubscriber extends MiddlewareSubscriber {
11
- constructor({ agent, logger, packageName = 'express' }) {
12
- super({ agent, logger, packageName, channelName: 'nr_use', system: 'Expressjs' })
10
+ class ExpressUseSubscriber extends ExpressSubscriber {
11
+ constructor({ agent, logger, packageName }) {
12
+ super({ agent, logger, packageName, channelName: 'nr_use' })
13
13
  }
14
14
 
15
15
  handler(data) {
@@ -66,11 +66,22 @@ class MessageConsumerSubscriber extends Subscriber {
66
66
  }
67
67
 
68
68
  /**
69
- * Ends the transaction created for the consumption callback.
69
+ * Checks the result of the message handler.
70
+ * If it's a promise, waits for it to resolve before ending transaction.
71
+ * This ensures that the transaction stays active until the promise resolves.
72
+ * @param {object} data the data associated with the `asyncEnd` event
70
73
  */
71
- asyncEnd() {
74
+ asyncEnd(data) {
72
75
  const ctx = this.agent.tracer.getContext()
73
- ctx?.transaction?.end()
76
+ const result = data.cbResult
77
+ if (typeof result?.then === 'function') {
78
+ const prom = Promise.resolve(result)
79
+ prom.finally(() => {
80
+ ctx?.transaction?.end()
81
+ })
82
+ } else {
83
+ ctx?.transaction?.end()
84
+ }
74
85
  }
75
86
 
76
87
  enable() {
@@ -19,6 +19,17 @@ function getFunctionName(handler) {
19
19
  return handler.name === '' ? '<anonymous>' : handler.name
20
20
  }
21
21
 
22
+ /**
23
+ * Default error handler for determining if error should stored with transaction.
24
+ * Note: Based on previous shim instrumentation only Express, Restify, and Hapi have
25
+ * a different handler.
26
+ * @param {Error} err error passed to done handler
27
+ * @returns {boolean} returns true if error exists
28
+ */
29
+ function defaultErrorHandler(err) {
30
+ return err
31
+ }
32
+
22
33
  /**
23
34
  * The baseline parameters available to the middleware wrapper
24
35
  *
@@ -26,6 +37,7 @@ function getFunctionName(handler) {
26
37
  * @property {object} agent A New Relic Node.js agent instance.
27
38
  * @property {object} logger An agent logger instance.
28
39
  * @property {string} system handling the instrumentation(i.e - Fastify, Expressjs, Hapi, etc)
40
+ * @property {Function} [errorHandler] optional function to determine if error should be recorded
29
41
  */
30
42
 
31
43
  /**
@@ -36,13 +48,14 @@ function getFunctionName(handler) {
36
48
  * @property {string} prefix formatted prefix to name segments/timeslice metrics
37
49
  */
38
50
  class MiddlewareWrapper {
39
- constructor({ agent, logger, system }) {
51
+ constructor({ agent, logger, system, errorHandler }) {
40
52
  this.agent = agent
41
53
  this.logger = logger
42
54
  this.system = system
43
55
  this.config = agent.config
44
56
  this.prefix = `Nodejs/Middleware/${this.system}`
45
57
  this.agent.environment.setFramework(system)
58
+ this.isError = errorHandler ?? defaultErrorHandler
46
59
  }
47
60
 
48
61
  /**
@@ -180,7 +193,7 @@ class MiddlewareWrapper {
180
193
  if (isSync) {
181
194
  function wrappedDone(...doneArgs) {
182
195
  const [err] = doneArgs
183
- if (err) {
196
+ if (self.isError(err)) {
184
197
  self.storeError(txInfo, err)
185
198
  // route has been completed, pop from path
186
199
  // to allow other handlers to name it more accurately
@@ -8,12 +8,12 @@ const Subscriber = require('./base')
8
8
  const MiddlewareWrapper = require('./middleware-wrapper')
9
9
 
10
10
  class MiddlewareSubscriber extends Subscriber {
11
- constructor({ agent, logger, packageName, channelName, system }) {
11
+ constructor({ agent, logger, packageName, channelName, system, errorHandler }) {
12
12
  super({ agent, logger, packageName, channelName })
13
13
  // this is because the handler simply wraps a function
14
14
  // that is executed later when a request is made
15
15
  this.requireActiveTx = false
16
- this.wrapper = new MiddlewareWrapper({ agent, logger, system })
16
+ this.wrapper = new MiddlewareWrapper({ agent, logger, system, errorHandler })
17
17
  }
18
18
  }
19
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "13.6.4",
3
+ "version": "13.6.5",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [