This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-nodejs.git
The following commit(s) were added to refs/heads/master by this push:
new 7103eba Modify mongoose call xxxx() throwing "is not a function"
(#128)
7103eba is described below
commit 7103ebab4f448836c7677256e4c19fe53e9787f7
Author: shivendoodeshmukh <[email protected]>
AuthorDate: Fri Aug 22 18:34:09 2025 +0530
Modify mongoose call xxxx() throwing "is not a function" (#128)
---
src/plugins/MongoosePlugin.ts | 38 +++++++++++++++++++++++++++++--
tests/plugins/mongoose/client.ts | 1 +
tests/plugins/mongoose/expected.data.yaml | 19 ++++++++++++++--
3 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/src/plugins/MongoosePlugin.ts b/src/plugins/MongoosePlugin.ts
index 234abd5..e5348d4 100644
--- a/src/plugins/MongoosePlugin.ts
+++ b/src/plugins/MongoosePlugin.ts
@@ -118,7 +118,6 @@ class MongoosePlugin implements SwPlugin {
arguments[arguments.length - 1] = function () {
// in case of immediate synchronous callback from mongoose
(span as any).mongooseInCall = false;
-
wrappedCallback.apply(this, arguments as any);
};
}
@@ -130,7 +129,42 @@ class MongoosePlugin implements SwPlugin {
if (!hasCB) {
if (ret && typeof ret.then === 'function') {
// generic Promise check
- ret = wrapPromise(span, ret);
+
+ if (ret.constructor.name != 'Query') {
+ ret = wrapPromise(span, ret);
+ } else {
+ // Mongoose Query object
+ const chainMethods = ['select', 'sort', 'skip', 'limit',
'populate'];
+
+ // Mongoose Query object
+ const originalThen = ret.then;
+ const originalExec = ret.exec;
+ const originalLean = ret.lean;
+
+ // Preserve the query chain methods using arrow functions to
maintain context
+ ret.then = (...args: any[]) => wrapPromise(span,
originalThen.apply(ret, args));
+ ret.exec = (...args: any[]) => wrapPromise(span,
originalExec.apply(ret, args));
+ ret.lean = (...args: any[]) => {
+ const leanQuery = originalLean.apply(ret, args);
+ // Preserve other chain methods on the lean result
+ leanQuery.then = ret.then;
+ leanQuery.exec = ret.exec;
+ return leanQuery;
+ };
+ // Wrap other common query methods that might be chained
+ chainMethods.forEach((method) => {
+ if (ret[method]) {
+ const originalMethod = ret[method];
+ ret[method] = (...args: any[]) => {
+ const result = originalMethod.apply(ret, args);
+ result.then = ret.then;
+ result.exec = ret.exec;
+ result.lean = ret.lean;
+ return result;
+ };
+ }
+ });
+ }
} else {
// no callback passed in and no Promise or Cursor returned, play
it safe
span.stop();
diff --git a/tests/plugins/mongoose/client.ts b/tests/plugins/mongoose/client.ts
index 25ff2b3..c3f4ed3 100644
--- a/tests/plugins/mongoose/client.ts
+++ b/tests/plugins/mongoose/client.ts
@@ -21,6 +21,7 @@ import * as http from 'http';
import agent from '../../../src';
process.env.SW_AGENT_LOGGING_LEVEL = 'ERROR';
+process.env.SW_AGENT_DISABLE_PLUGINS = 'MongoDBPlugin';
agent.start({
serviceName: 'client',
diff --git a/tests/plugins/mongoose/expected.data.yaml
b/tests/plugins/mongoose/expected.data.yaml
index 452d72b..a2400d8 100644
--- a/tests/plugins/mongoose/expected.data.yaml
+++ b/tests/plugins/mongoose/expected.data.yaml
@@ -35,7 +35,7 @@ segmentItems:
tags:
- { key: db.type, value: MongoDB }
- { key: db.instance, value: admin }
- - { key: db.statement, value: 'collection("tests")' }
+ - { key: db.statement, 'collection("tests")' }
- operationName: Mongoose/ensureIndexes
operationId: 0
parentSpanId: 0
@@ -50,6 +50,21 @@ segmentItems:
tags:
- { key: db.type, value: MongoDB }
- { key: db.instance, value: admin }
+ - operationName: MongoDB/find # This is the required span
+ operationId: 0
+ parentSpanId: 0
+ spanId: 4
+ spanLayer: Database
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 9
+ spanType: Exit
+ peer: mongo:27017
+ skipAnalysis: false
+ tags:
+ - { key: db.type, value: MongoDB }
+ - { key: db.instance, value: admin }
+ - { key: db.statement, 'tests.find({})' }
- operationName: Mongoose/find
operationId: 0
parentSpanId: 0
@@ -64,7 +79,7 @@ segmentItems:
tags:
- { key: db.type, value: MongoDB }
- { key: db.instance, value: admin }
- - { key: db.statement, value: 'tests.find({})' }
+ # The mongoose find span might not have the db.statement, which
is fine
- operationName: GET:/mongoose
operationId: 0
parentSpanId: -1