import { isThenable, SEMANTIC_ATTRIBUTE_SENTRY_OP, continueTrace, startNewTrace, captureException, startSpan, isObjectLike, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { getOriginalWaitUntil, flushAndDispose } from './flush.js'; import { ensureInstrumented } from './instrument.js'; import { init } from './sdk.js'; import { withInvocationIsolationScope } from './utils/invocationScope.js'; import { extractRpcMeta } from './utils/rpcMeta.js'; import { getStoredSpanContext, buildSpanLinks, storeSpanContext } from './utils/traceLinks.js'; function resolveOriginalStorage(context, thisArg) { if (isObjectLike(thisArg) && "ctx" in thisArg) { const doCtx = thisArg.ctx; if (doCtx?.originalStorage) { return doCtx.originalStorage; } } if (context && "originalStorage" in context && context.originalStorage) { return context.originalStorage; } return void 0; } function wrapMethodWithSentry(wrapperOptions, handler, callback, noMark) { return ensureInstrumented( handler, (original) => new Proxy(original, { apply(target, thisArg, rawArgs) { const { startNewTrace: startNewTrace$1, origin } = wrapperOptions; let args = rawArgs; let rpcMeta; if (wrapperOptions.spanOp === "rpc") { const extracted = extractRpcMeta(rawArgs); args = extracted.args; rpcMeta = extracted.rpcMeta; } const spanName = typeof wrapperOptions.spanName === "function" ? wrapperOptions.spanName(rpcMeta) : wrapperOptions.spanName; const wrappedFunction = (scope) => { const context = wrapperOptions.context; const waitUntil = context ? getOriginalWaitUntil(context)?.bind(context) : void 0; const storage = resolveOriginalStorage(context, thisArg); let scopeClient = scope.getClient(); if (startNewTrace$1 || !scopeClient?.getTransport()) { const client = init({ ...wrapperOptions.options, ctx: context }); scope.setClient(client); scopeClient = client; } const clientToDispose = scopeClient; const methodName = spanName || "unknown"; const teardown = async () => { if (startNewTrace$1 && storage) { storeSpanContext(storage, methodName); } await flushAndDispose(clientToDispose); }; const onFulfilled = (res) => { waitUntil?.(teardown()); return res; }; const onRejected = (e) => { captureException(e, { mechanism: { type: origin, handled: false } }); waitUntil?.(teardown()); throw e; }; if (!spanName) { try { if (callback) { callback(...args); } const result = Reflect.apply(target, thisArg, args); if (isThenable(result)) { return result.then(onFulfilled, onRejected); } else { return onFulfilled(result); } } catch (e) { return onRejected(e); } } const attributes = wrapperOptions.spanOp ? { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: origin } : {}; const executeSpan = () => { return startSpan({ name: methodName, attributes }, (span) => { if (startNewTrace$1 && storage) { const storedContext = getStoredSpanContext(storage, methodName); if (storedContext) { span.addLinks(buildSpanLinks(storedContext)); const sampledFlag = storedContext.sampled ? "1" : "0"; span.setAttribute( "sentry.previous_trace", `${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}` ); } } try { const result = Reflect.apply(target, thisArg, args); if (isThenable(result)) { return result.then(onFulfilled, onRejected); } else { return onFulfilled(result); } } catch (e) { return onRejected(e); } }); }; if (rpcMeta) { return continueTrace( { sentryTrace: rpcMeta["sentry-trace"] || "", baggage: rpcMeta.baggage || "" }, executeSpan ); } if (startNewTrace$1) { return startNewTrace(() => executeSpan()); } return executeSpan(); }; return withInvocationIsolationScope(wrappedFunction); } }), noMark ); } export { wrapMethodWithSentry }; //# sourceMappingURL=wrapMethodWithSentry.js.map