import { getClient, withIsolationScope, withScope, isThenable, SEMANTIC_ATTRIBUTE_SENTRY_OP, continueTrace, startNewTrace, captureException, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { flushAndDispose } from './flush.js'; import { ensureInstrumented } from './instrument.js'; import { init } from './sdk.js'; import { extractRpcMeta } from './utils/rpcMeta.js'; import { getStoredSpanContext, buildSpanLinks, storeSpanContext } from './utils/traceLinks.js'; function resolveOriginalStorage(context, thisArg) { if (thisArg && typeof thisArg === "object" && "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 } = wrapperOptions; let args = rawArgs; let rpcMeta; if (wrapperOptions.spanOp === "rpc") { const extracted = extractRpcMeta(rawArgs); args = extracted.args; rpcMeta = extracted.rpcMeta; } const currentClient = getClient(); const sentryWithScope = startNewTrace$1 ? withIsolationScope : currentClient ? withScope : withIsolationScope; const wrappedFunction = (scope) => { const context = wrapperOptions.context; const waitUntil = context?.waitUntil?.bind?.(context); 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 = wrapperOptions.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: "auto.faas.cloudflare.durable_object", handled: false } }); waitUntil?.(teardown()); throw e; }; if (!wrapperOptions.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]: "auto.faas.cloudflare.durable_object" } : {}; 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 sentryWithScope(wrappedFunction); } }), noMark ); } export { wrapMethodWithSentry }; //# sourceMappingURL=wrapMethodWithSentry.js.map