Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class InstanaAWSDynamoDB extends InstanaAWSProduct {
.catch(() => {
/* silently ignore failed attempts to get the region */
});
} else {
tracingUtil.handleUnexpectedReturnValue(regionPromise, span, this.spanName, 'config.region()');
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,23 @@ function instrument(SQSConsumer) {
span.disableAutoEnd();
const res = orig.apply(this, arguments);

res
.then(() => {
span.d = Date.now() - span.ts;
span.transmitManual();
})
.catch(err => {
span.ec = 1;
tracingUtil.setErrorDetails(span, err, 'sqs');
span.d = Date.now() - span.ts;
span.transmitManual();
});
if (res && typeof res.then === 'function') {
res
.then(() => {
span.d = Date.now() - span.ts;
span.transmitManual();
})
.catch(err => {
span.ec = 1;
tracingUtil.setErrorDetails(span, err, 'sqs');
span.d = Date.now() - span.ts;
span.transmitManual();
});
} else {
tracingUtil.handleUnexpectedReturnValue(res, span, 'sqs', 'consumer handler');
span.d = Date.now() - span.ts;
span.transmitManual();
}

return res;
});
Expand All @@ -56,17 +62,23 @@ function instrument(SQSConsumer) {
span.disableAutoEnd();
const res = orig.apply(this, arguments);

res
.then(() => {
span.d = Date.now() - span.ts;
span.transmitManual();
})
.catch(err => {
span.ec = 1;
tracingUtil.setErrorDetails(span, err, 'sqs');
span.d = Date.now() - span.ts;
span.transmitManual();
});
if (res && typeof res.then === 'function') {
res
.then(() => {
span.d = Date.now() - span.ts;
span.transmitManual();
})
.catch(err => {
span.ec = 1;
tracingUtil.setErrorDetails(span, err, 'sqs');
span.d = Date.now() - span.ts;
span.transmitManual();
});
} else if (res !== undefined) {
tracingUtil.handleUnexpectedReturnValue(res, span, 'sqs', 'consumer batch handler');
span.d = Date.now() - span.ts;
span.transmitManual();
}

return res;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ function instrumentingOperation({
op
};
const promise = originalQuery.apply(ctx, argsForOriginalQuery);
if (promise && typeof promise.then === 'function') {

if (promise && typeof promise?.then === 'function') {
promise
.then(value => {
finishSpan(null, span);
Expand All @@ -97,6 +98,9 @@ function instrumentingOperation({
finishSpan(error, span);
return error;
});
} else {
tracingUtil.handleUnexpectedReturnValue(promise, span, 'azstorage', 'blob operation');
finishSpan(null, span);
}
return promise;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ function instrumentedPublishMessage(ctx, originalPublishMessage, originalArgs) {
throw err;
}
);
} else if (!originalCallback) {
// If there's no callback and no promise, we need to finish the span
// This can happen in some edge cases
tracingUtil.handleUnexpectedReturnValue(thenable, span, 'gcps', 'publish message');
finishSpan(null, null, span);
}
return thenable;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,11 +416,14 @@ function instrumentedOperation(operation, extractorPre, extractorPost, ctx, orig
}

const promise = original.apply(ctx, originalArgs);
if (promise) {
if (promise && typeof promise.then === 'function') {
promise.then(
result => finishSpan(null, Array.isArray(result) ? result[0] : result, span, extractorPost),
e => finishSpan(e, null, span, extractorPost)
);
} else {
tracingUtil.handleUnexpectedReturnValue(promise, span, 'gcs', operation);
finishSpan(null, null, span, extractorPost);
}
return promise;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
const shimmer = require('../../shimmer');

const hook = require('../../../util/hook');
const tracingUtil = require('../../tracingUtil');
const cls = require('../../cls');

let isActive = false;
Expand Down Expand Up @@ -62,18 +63,29 @@ function shimPushValue(originalFunction) {
function shimPullValue(originalFunction) {
return function () {
const pullPromise = originalFunction.apply(this, arguments);
return pullPromise.then(result => {
if (result && result.value && result.value[CLS_CONTEXT_SYMBOL]) {
const clsContext = result.value[CLS_CONTEXT_SYMBOL];
if (isActive && clsContext) {
cls.ns.enter(clsContext);
setImmediate(() => {
cls.ns.exit(clsContext);
});

if (pullPromise && typeof pullPromise.then === 'function') {
return pullPromise.then(result => {
if (result && result.value && result.value[CLS_CONTEXT_SYMBOL]) {
const clsContext = result.value[CLS_CONTEXT_SYMBOL];
if (isActive && clsContext) {
cls.ns.enter(clsContext);
setImmediate(() => {
cls.ns.exit(clsContext);
});
}
}
return result;
});
} else {
// will the context change ? Maybe check and remove this case
const span = cls.getCurrentSpan();
if (span) {
tracingUtil.handleUnexpectedReturnValue(pullPromise, span, 'graphql.subscription', 'pull value');
}
return result;
});
}

return pullPromise;
};
}

Expand Down
59 changes: 42 additions & 17 deletions packages/core/src/tracing/instrumentation/databases/couchbase.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ function instrumentConnect(originalConnect) {

const prom = originalConnect.apply(originalThis, originalArgs);

if (prom && prom.then) {
if (prom && typeof prom.then === 'function') {
prom.then(cluster => {
instrumentCluster(cluster, connectionStr);
return cluster;
Expand Down Expand Up @@ -426,7 +426,7 @@ function instrumentTransactions(cluster, connectionStr) {

const result = originalFn.apply(this, arguments);

if (result.then && result.catch) {
if (result && result?.then && result?.catch) {
result
.then(() => {
span.d = Date.now() - span.ts;
Expand Down Expand Up @@ -486,9 +486,19 @@ function instrumentOperation({ connectionStr, bucketName, getBucketTypeFn, sql,
const { originalCallback, callbackIndex } = tracingUtil.findCallback(originalArgs);

if (callbackIndex < 0) {
const prom = original.apply(originalThis, originalArgs);
// Case 4: Handle synchronous validation errors for promise-based calls
let prom;
try {
prom = original.apply(originalThis, originalArgs);
} catch (syncError) {
span.ec = 1;
tracingUtil.setErrorDetails(span, syncError, 'couchbase');
span.d = Date.now() - span.ts;
span.transmit();
throw syncError;
}

if (prom.then && prom.catch) {
if (typeof prom?.then === 'function' && typeof prom?.catch === 'function') {
prom
.then(result => {
if (resultHandler) {
Expand All @@ -505,27 +515,42 @@ function instrumentOperation({ connectionStr, bucketName, getBucketTypeFn, sql,
span.d = Date.now() - span.ts;
span.transmit();
});
} else if (prom !== undefined) {
// Case 5: Use utility function
tracingUtil.handleUnexpectedReturnValue(prom, span, 'couchbase', 'operation');

span.d = Date.now() - span.ts;
span.transmit();
}

return prom;
} else {
originalArgs[callbackIndex] = cls.ns.bind(function instanaCallback(err, result) {
if (err) {
span.ec = 1;
tracingUtil.setErrorDetails(span, err, 'couchbase');
}
// Case 4: Handle synchronous validation errors for callback-based calls
try {
originalArgs[callbackIndex] = cls.ns.bind(function instanaCallback(err, result) {
if (err) {
span.ec = 1;
tracingUtil.setErrorDetails(span, err, 'couchbase');
}

if (resultHandler) {
resultHandler(span, result);
}
if (resultHandler) {
resultHandler(span, result);
}

span.d = Date.now() - span.ts;
span.transmit();
span.d = Date.now() - span.ts;
span.transmit();

return originalCallback.apply(this, arguments);
});
return originalCallback.apply(this, arguments);
});

return original.apply(originalThis, originalArgs);
return original.apply(originalThis, originalArgs);
} catch (syncError) {
span.ec = 1;
tracingUtil.setErrorDetails(span, syncError, 'couchbase');
span.d = Date.now() - span.ts;
span.transmit();
throw syncError;
}
}
});
};
Expand Down
8 changes: 6 additions & 2 deletions packages/core/src/tracing/instrumentation/databases/db2.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ function instrumentQueryHelper(ctx, originalArgs, originalFunction, stmt, isAsyn
return originalFunction.apply(ctx, originalArgs);
}

// Case 4: Handle synchronous validation errors for promise-based calls
const resultPromise = originalFunction.apply(ctx, originalArgs);

if (resultPromise && typeof resultPromise.then === 'function' && typeof resultPromise.catch === 'function') {
Expand All @@ -328,9 +329,12 @@ function instrumentQueryHelper(ctx, originalArgs, originalFunction, stmt, isAsyn
finishSpan(ctx, null, span);
return err;
});

return resultPromise;
} else {
tracingUtil.handleUnexpectedReturnValue(resultPromise, span, 'ibmdb2', 'query');
finishSpan(ctx, null, span);
}

return resultPromise;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,17 @@ function instrumentApi(client, actionPath, clusterInfo) {
} else {
// eslint-disable-next-line no-useless-catch
try {
return originalFunction.apply(ctx, originalArgs).then(onSuccess.bind(null, span), error => {
onError(span, error);
throw error;
});
const promise = originalFunction.apply(ctx, originalArgs);
if (typeof promise?.then === 'function') {
return promise.then(onSuccess.bind(null, span), error => {
onError(span, error);
throw error;
});
} else {
tracingUtil.handleUnexpectedReturnValue(promise, span, 'elasticsearch', `action "${action}"`);
onSuccess(span, {});
}
return promise;
} catch (e) {
// Immediately cleanup on synchronous errors.
throw e;
Expand Down Expand Up @@ -448,10 +455,17 @@ function instrumentedRequest(ctx, origEsReq, originalArgs) {
} else {
// eslint-disable-next-line no-useless-catch
try {
return origEsReq.apply(ctx, originalArgs).then(onSuccess.bind(null, span), error => {
onError(span, error);
throw error;
});
const promise = origEsReq.apply(ctx, originalArgs);
if (typeof promise?.then === 'function') {
return promise.then(onSuccess.bind(null, span), error => {
onError(span, error);
throw error;
});
} else {
tracingUtil.handleUnexpectedReturnValue(promise, span, 'elasticsearch', 'transport request');
onSuccess(span, {});
}
return promise;
} catch (e) {
// Immediately cleanup on synchronous errors.
throw e;
Expand Down
20 changes: 14 additions & 6 deletions packages/core/src/tracing/instrumentation/databases/ioredis.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,16 @@ function instrumentSendCommand(original) {
span.stack = tracingUtil.getStackTrace(wrappedInternalSendCommand);

callback = cls.ns.bind(onResult);
command.promise.then(
// make sure that the first parameter is never truthy
callback.bind(null, null),
callback
);
if (typeof command.promise?.then === 'function') {
command.promise.then(
// make sure that the first parameter is never truthy
callback.bind(null, null),
callback
);
} else {
tracingUtil.handleUnexpectedReturnValue(command.promise, span, 'redis', `command "${command.name}"`);
callback(null);
}

return original.apply(client, argsForOriginal);

Expand Down Expand Up @@ -190,7 +195,7 @@ function instrumentMultiOrPipelineExec(clsContextForMultiOrPipeline, commandName
span.ts = Date.now();

const result = original.apply(this, arguments);
if (result.then) {
if (typeof result?.then === 'function') {
result.then(
results => {
endCallback.call(null, clsContextForMultiOrPipeline, span, null, results);
Expand All @@ -199,6 +204,9 @@ function instrumentMultiOrPipelineExec(clsContextForMultiOrPipeline, commandName
endCallback.call(null, clsContextForMultiOrPipeline, span, error, []);
}
);
} else if (result !== undefined) {
tracingUtil.handleUnexpectedReturnValue(result, span, 'redis', `${commandName} exec`);
endCallback.call(null, clsContextForMultiOrPipeline, span, null, []);
}
return result;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ function handleCallbackOrPromise(ctx, originalArgs, originalFunction, span) {

const resultPromise = originalFunction.apply(ctx, originalArgs);

if (resultPromise && resultPromise.then) {
if (resultPromise && typeof resultPromise.then === 'function') {
resultPromise
.then(result => {
span.d = Date.now() - span.ts;
Expand All @@ -471,6 +471,11 @@ function handleCallbackOrPromise(ctx, originalArgs, originalFunction, span) {
span.transmit();
return err;
});
} else {
tracingUtil.handleUnexpectedReturnValue(resultPromise, span, 'mongo', 'command');

span.d = Date.now() - span.ts;
span.transmit();
}

return resultPromise;
Expand Down
Loading