@sentry/cloudflare 11.0.0-beta.2 → 11.0.0-rc.1
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/build/cjs/dev/durableobject.js +26 -18
- package/build/cjs/dev/durableobject.js.map +1 -1
- package/build/cjs/dev/index.js +5 -1
- package/build/cjs/dev/index.js.map +1 -1
- package/build/cjs/dev/instrumentations/instrumentDurableObjectNamespace.js +6 -0
- package/build/cjs/dev/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentD1.js +19 -17
- package/build/cjs/dev/instrumentations/worker/instrumentD1.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentEmail.js +4 -3
- package/build/cjs/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js +10 -5
- package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/cjs/dev/integrations/fetch.js +3 -101
- package/build/cjs/dev/integrations/fetch.js.map +1 -1
- package/build/cjs/dev/orchestrion-deferred-channels.js +39 -0
- package/build/cjs/dev/orchestrion-deferred-channels.js.map +1 -0
- package/build/cjs/dev/orchestrion-diagnostics-channel.js +83 -0
- package/build/cjs/dev/orchestrion-diagnostics-channel.js.map +1 -0
- package/build/cjs/dev/vite/flueRuntime.js +44 -0
- package/build/cjs/dev/vite/flueRuntime.js.map +1 -0
- package/build/cjs/dev/vite/index.js +8 -1
- package/build/cjs/dev/vite/index.js.map +1 -1
- package/build/cjs/dev/vite/mastraObservability.js +39 -0
- package/build/cjs/dev/vite/mastraObservability.js.map +1 -0
- package/build/cjs/dev/wrapMethodWithSentry.js +8 -4
- package/build/cjs/dev/wrapMethodWithSentry.js.map +1 -1
- package/build/cjs/dev/wrapRequestHandlerWithInit.js +2 -0
- package/build/cjs/dev/wrapRequestHandlerWithInit.js.map +1 -1
- package/build/cjs/prod/durableobject.js +26 -18
- package/build/cjs/prod/durableobject.js.map +1 -1
- package/build/cjs/prod/index.js +5 -1
- package/build/cjs/prod/index.js.map +1 -1
- package/build/cjs/prod/instrumentations/instrumentDurableObjectNamespace.js +6 -0
- package/build/cjs/prod/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentD1.js +19 -17
- package/build/cjs/prod/instrumentations/worker/instrumentD1.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentEmail.js +4 -3
- package/build/cjs/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js +10 -5
- package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/cjs/prod/integrations/fetch.js +3 -101
- package/build/cjs/prod/integrations/fetch.js.map +1 -1
- package/build/cjs/prod/orchestrion-deferred-channels.js +39 -0
- package/build/cjs/prod/orchestrion-deferred-channels.js.map +1 -0
- package/build/cjs/prod/orchestrion-diagnostics-channel.js +83 -0
- package/build/cjs/prod/orchestrion-diagnostics-channel.js.map +1 -0
- package/build/cjs/prod/vite/flueRuntime.js +44 -0
- package/build/cjs/prod/vite/flueRuntime.js.map +1 -0
- package/build/cjs/prod/vite/index.js +8 -1
- package/build/cjs/prod/vite/index.js.map +1 -1
- package/build/cjs/prod/vite/mastraObservability.js +39 -0
- package/build/cjs/prod/vite/mastraObservability.js.map +1 -0
- package/build/cjs/prod/wrapMethodWithSentry.js +8 -4
- package/build/cjs/prod/wrapMethodWithSentry.js.map +1 -1
- package/build/cjs/prod/wrapRequestHandlerWithInit.js +2 -0
- package/build/cjs/prod/wrapRequestHandlerWithInit.js.map +1 -1
- package/build/esm/dev/durableobject.js +27 -19
- package/build/esm/dev/durableobject.js.map +1 -1
- package/build/esm/dev/index.js +2 -2
- package/build/esm/dev/instrumentations/instrumentDurableObjectNamespace.js +6 -0
- package/build/esm/dev/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentD1.js +20 -18
- package/build/esm/dev/instrumentations/worker/instrumentD1.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentEmail.js +6 -5
- package/build/esm/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentScheduled.js +12 -7
- package/build/esm/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/esm/dev/integrations/fetch.js +4 -102
- package/build/esm/dev/integrations/fetch.js.map +1 -1
- package/build/esm/dev/orchestrion-deferred-channels.js +35 -0
- package/build/esm/dev/orchestrion-deferred-channels.js.map +1 -0
- package/build/esm/dev/orchestrion-diagnostics-channel.js +77 -0
- package/build/esm/dev/orchestrion-diagnostics-channel.js.map +1 -0
- package/build/esm/dev/package.json +1 -1
- package/build/esm/dev/vite/flueRuntime.js +41 -0
- package/build/esm/dev/vite/flueRuntime.js.map +1 -0
- package/build/esm/dev/vite/index.js +8 -1
- package/build/esm/dev/vite/index.js.map +1 -1
- package/build/esm/dev/vite/mastraObservability.js +36 -0
- package/build/esm/dev/vite/mastraObservability.js.map +1 -0
- package/build/esm/dev/wrapMethodWithSentry.js +7 -3
- package/build/esm/dev/wrapMethodWithSentry.js.map +1 -1
- package/build/esm/dev/wrapRequestHandlerWithInit.js +2 -0
- package/build/esm/dev/wrapRequestHandlerWithInit.js.map +1 -1
- package/build/esm/prod/durableobject.js +27 -19
- package/build/esm/prod/durableobject.js.map +1 -1
- package/build/esm/prod/index.js +2 -2
- package/build/esm/prod/instrumentations/instrumentDurableObjectNamespace.js +6 -0
- package/build/esm/prod/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentD1.js +20 -18
- package/build/esm/prod/instrumentations/worker/instrumentD1.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentEmail.js +6 -5
- package/build/esm/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentScheduled.js +12 -7
- package/build/esm/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/esm/prod/integrations/fetch.js +4 -102
- package/build/esm/prod/integrations/fetch.js.map +1 -1
- package/build/esm/prod/orchestrion-deferred-channels.js +35 -0
- package/build/esm/prod/orchestrion-deferred-channels.js.map +1 -0
- package/build/esm/prod/orchestrion-diagnostics-channel.js +77 -0
- package/build/esm/prod/orchestrion-diagnostics-channel.js.map +1 -0
- package/build/esm/prod/package.json +1 -1
- package/build/esm/prod/vite/flueRuntime.js +41 -0
- package/build/esm/prod/vite/flueRuntime.js.map +1 -0
- package/build/esm/prod/vite/index.js +8 -1
- package/build/esm/prod/vite/index.js.map +1 -1
- package/build/esm/prod/vite/mastraObservability.js +36 -0
- package/build/esm/prod/vite/mastraObservability.js.map +1 -0
- package/build/esm/prod/wrapMethodWithSentry.js +7 -3
- package/build/esm/prod/wrapMethodWithSentry.js.map +1 -1
- package/build/esm/prod/wrapRequestHandlerWithInit.js +2 -0
- package/build/esm/prod/wrapRequestHandlerWithInit.js.map +1 -1
- package/build/types/durableobject.d.ts +3 -2
- package/build/types/durableobject.d.ts.map +1 -1
- package/build/types/index.d.ts +5 -3
- package/build/types/index.d.ts.map +1 -1
- package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts +1 -0
- package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentD1.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentEmail.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentScheduled.d.ts.map +1 -1
- package/build/types/integrations/fetch.d.ts +1 -15
- package/build/types/integrations/fetch.d.ts.map +1 -1
- package/build/types/orchestrion-deferred-channels.d.ts +26 -0
- package/build/types/orchestrion-deferred-channels.d.ts.map +1 -0
- package/build/types/orchestrion-diagnostics-channel.d.ts +44 -0
- package/build/types/orchestrion-diagnostics-channel.d.ts.map +1 -0
- package/build/types/vite/flueRuntime.d.ts +23 -0
- package/build/types/vite/flueRuntime.d.ts.map +1 -0
- package/build/types/vite/index.d.ts.map +1 -1
- package/build/types/vite/mastraObservability.d.ts +27 -0
- package/build/types/vite/mastraObservability.d.ts.map +1 -0
- package/build/types/wrapMethodWithSentry.d.ts.map +1 -1
- package/build/types/wrapRequestHandlerWithInit.d.ts.map +1 -1
- package/package.json +10 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentScheduled.js","sources":["../../../../../src/instrumentations/worker/instrumentScheduled.ts"],"sourcesContent":["import type { ScheduledController } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport {
|
|
1
|
+
{"version":3,"file":"instrumentScheduled.js","sources":["../../../../../src/instrumentations/worker/instrumentScheduled.ts"],"sourcesContent":["import type { ScheduledController } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n FAAS_CRON,\n FAAS_TIME,\n FAAS_TRIGGER,\n SENTRY_DESCRIPTION,\n SENTRY_ORIGIN,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, hasSpanStreamingEnabled, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\nfunction wrapScheduledHandler(\n controller: ScheduledController,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n const description = `Scheduled Cron ${controller.cron}`;\n\n return startSpan(\n {\n name: client && hasSpanStreamingEnabled(client) ? 'scheduled' : description,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n // override description inference by Relay to preserve the original (transaction-based) description.\n // sentry-conventions can't map the special case for the \"Scheduled Cron\" prefix and the chron string.\n [SENTRY_DESCRIPTION]: description,\n [CODE_FUNCTION_NAME]: 'scheduled',\n [FAAS_CRON]: controller.cron,\n [FAAS_TIME]: new Date(controller.scheduledTime).toISOString(),\n [FAAS_TRIGGER]: 'timer',\n [SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.scheduled' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a scheduled handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerScheduled<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('scheduled' in handler) || typeof handler.scheduled !== 'function') {\n return;\n }\n\n handler.scheduled = ensureInstrumented(\n handler.scheduled,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['scheduled']>>) {\n const [controller, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapScheduledHandler(controller, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n\n/**\n * Instruments a scheduled method for WorkerEntrypoint (options/context already available).\n */\nexport function instrumentWorkerEntrypointScheduled<T extends WorkerEntrypoint>(\n instance: T,\n options: CloudflareOptions,\n context: ExecutionContext,\n): void {\n if (!instance.scheduled) {\n return;\n }\n\n const original = instance.scheduled.bind(instance);\n instance.scheduled = new Proxy(original, {\n apply(target, thisArg, args: [ScheduledController]) {\n const [controller] = args;\n\n return wrapScheduledHandler(controller, options, context, () => Reflect.apply(target, thisArg, args));\n },\n });\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","hasSpanStreamingEnabled","SENTRY_OP","FUNCTION","SENTRY_DESCRIPTION","CODE_FUNCTION_NAME","FAAS_CRON","FAAS_TIME","FAAS_TRIGGER","SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":"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"}
|
|
@@ -2,108 +2,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const core = require('@sentry/core');
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const breadcrumbs = options.breadcrumbs === void 0 ? true : options.breadcrumbs;
|
|
9
|
-
const shouldCreateSpanForRequest = options.shouldCreateSpanForRequest;
|
|
10
|
-
const _createSpanUrlMap = new core.LRUMap(100);
|
|
11
|
-
const _headersUrlMap = new core.LRUMap(100);
|
|
12
|
-
const spans = {};
|
|
13
|
-
function _shouldAttachTraceData(url) {
|
|
14
|
-
const client = core.getClient();
|
|
15
|
-
if (!client) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
return core.shouldPropagateTraceForUrl(url, client.getOptions().tracePropagationTargets, _headersUrlMap);
|
|
19
|
-
}
|
|
20
|
-
function _shouldCreateSpan(url) {
|
|
21
|
-
if (shouldCreateSpanForRequest === void 0) {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
const cachedDecision = _createSpanUrlMap.get(url);
|
|
25
|
-
if (cachedDecision !== void 0) {
|
|
26
|
-
return cachedDecision;
|
|
27
|
-
}
|
|
28
|
-
const decision = shouldCreateSpanForRequest(url);
|
|
29
|
-
_createSpanUrlMap.set(url, decision);
|
|
30
|
-
return decision;
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
name: INTEGRATION_NAME,
|
|
34
|
-
setupOnce() {
|
|
35
|
-
core.addFetchInstrumentationHandler((handlerData) => {
|
|
36
|
-
const client = core.getClient();
|
|
37
|
-
const { propagateTraceparent } = client?.getOptions() || {};
|
|
38
|
-
if (!client || !HAS_CLIENT_MAP.get(client)) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (core.isSentryRequestUrl(handlerData.fetchData.url, client)) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
core.instrumentFetchRequest(handlerData, _shouldCreateSpan, _shouldAttachTraceData, spans, {
|
|
45
|
-
spanOrigin: "auto.http.fetch",
|
|
46
|
-
propagateTraceparent
|
|
47
|
-
});
|
|
48
|
-
if (breadcrumbs) {
|
|
49
|
-
createBreadcrumb(handlerData);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
},
|
|
53
|
-
setup(client) {
|
|
54
|
-
HAS_CLIENT_MAP.set(client, true);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
5
|
+
const fetchIntegration = core.createFetchIntegration({
|
|
6
|
+
name: "Fetch",
|
|
7
|
+
spanOrigin: "auto.http.fetch"
|
|
57
8
|
});
|
|
58
|
-
const fetchIntegration = core.defineIntegration(_fetchIntegration);
|
|
59
|
-
function createBreadcrumb(handlerData) {
|
|
60
|
-
const { startTimestamp, endTimestamp } = handlerData;
|
|
61
|
-
if (!endTimestamp) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const breadcrumbData = {
|
|
65
|
-
method: handlerData.fetchData.method,
|
|
66
|
-
url: handlerData.fetchData.url
|
|
67
|
-
};
|
|
68
|
-
if (handlerData.error) {
|
|
69
|
-
const hint = {
|
|
70
|
-
data: handlerData.error,
|
|
71
|
-
input: handlerData.args,
|
|
72
|
-
startTimestamp,
|
|
73
|
-
endTimestamp
|
|
74
|
-
};
|
|
75
|
-
core.addBreadcrumb(
|
|
76
|
-
{
|
|
77
|
-
category: "fetch",
|
|
78
|
-
data: breadcrumbData,
|
|
79
|
-
level: "error",
|
|
80
|
-
type: "http"
|
|
81
|
-
},
|
|
82
|
-
hint
|
|
83
|
-
);
|
|
84
|
-
} else {
|
|
85
|
-
const response = handlerData.response;
|
|
86
|
-
breadcrumbData.request_body_size = handlerData.fetchData.request_body_size;
|
|
87
|
-
breadcrumbData.response_body_size = handlerData.fetchData.response_body_size;
|
|
88
|
-
breadcrumbData.status_code = response?.status;
|
|
89
|
-
const hint = {
|
|
90
|
-
input: handlerData.args,
|
|
91
|
-
response,
|
|
92
|
-
startTimestamp,
|
|
93
|
-
endTimestamp
|
|
94
|
-
};
|
|
95
|
-
const level = core.getBreadcrumbLogLevelFromHttpStatusCode(breadcrumbData.status_code);
|
|
96
|
-
core.addBreadcrumb(
|
|
97
|
-
{
|
|
98
|
-
category: "fetch",
|
|
99
|
-
data: breadcrumbData,
|
|
100
|
-
type: "http",
|
|
101
|
-
level
|
|
102
|
-
},
|
|
103
|
-
hint
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
9
|
|
|
108
10
|
exports.fetchIntegration = fetchIntegration;
|
|
109
11
|
//# sourceMappingURL=fetch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sources":["../../../../src/integrations/fetch.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"fetch.js","sources":["../../../../src/integrations/fetch.ts"],"sourcesContent":["import { createFetchIntegration } from '@sentry/core';\n\n/**\n * Creates spans and attaches tracing headers to fetch requests.\n */\nexport const fetchIntegration = createFetchIntegration({\n name: 'Fetch',\n spanOrigin: 'auto.http.fetch',\n});\n"],"names":["createFetchIntegration"],"mappings":";;;;AAKO,MAAM,mBAAmBA,2BAAA,CAAuB;AAAA,EACrD,IAAA,EAAM,OAAA;AAAA,EACN,UAAA,EAAY;AACd,CAAC;;;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const core = require('@sentry/core');
|
|
4
|
+
const debugBuild = require('./debug-build.js');
|
|
5
|
+
|
|
6
|
+
const deferred = [];
|
|
7
|
+
const DEFERRED = /* @__PURE__ */ Symbol("sentryOrchestrionDeferred");
|
|
8
|
+
function isGlobalScopeError(error) {
|
|
9
|
+
return error instanceof Error && /within global scope/.test(error.message);
|
|
10
|
+
}
|
|
11
|
+
function deferChannelEvent(channel, ctx) {
|
|
12
|
+
if (ctx[DEFERRED]) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
ctx[DEFERRED] = true;
|
|
16
|
+
deferred.push({ channel, ctx, hadError: "error" in ctx });
|
|
17
|
+
}
|
|
18
|
+
function flushDeferredChannelEvents() {
|
|
19
|
+
if (deferred.length === 0) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const pending = deferred.splice(0, deferred.length);
|
|
23
|
+
for (const { channel, ctx, hadError } of pending) {
|
|
24
|
+
try {
|
|
25
|
+
channel.start.publish(ctx);
|
|
26
|
+
if (hadError) {
|
|
27
|
+
channel.error.publish(ctx);
|
|
28
|
+
}
|
|
29
|
+
channel.end.publish(ctx);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
debugBuild.DEBUG_BUILD && core.debug.warn("[orchestrion] failed to emit a deferred channel event", error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
exports.deferChannelEvent = deferChannelEvent;
|
|
37
|
+
exports.flushDeferredChannelEvents = flushDeferredChannelEvents;
|
|
38
|
+
exports.isGlobalScopeError = isGlobalScopeError;
|
|
39
|
+
//# sourceMappingURL=orchestrion-deferred-channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrion-deferred-channels.js","sources":["../../../src/orchestrion-deferred-channels.ts"],"sourcesContent":["/**\n * Deferral for orchestrion channel events that could not be published when they occurred.\n *\n * On workerd, `channel.publish()`/`runStores()` throw at module/global scope, so a library\n * instantiated at module scope (`const app = new Hono()`) cannot emit its wrapping event\n * there. {@link ./orchestrion-diagnostics-channel} defers those events here;\n * {@link flushDeferredChannelEvents} emits them once a request is being handled (where\n * publish works) and the SDK's `init()` has registered subscribers.\n *\n * This module imports NO `node:*` builtin, so it is safe to pull into the request wrapper on\n * runtimes without `nodejs_compat` — there the queue is always empty (no channels were ever\n * injected) and the flush is a no-op.\n */\nimport { debug } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\n\ntype Ctx = Record<string, unknown>;\n\n// The minimal slice of a `node:diagnostics_channel` TracingChannel we emit on. Declared locally\n// (rather than imported from `node:diagnostics_channel`) so this module's graph carries no `node:`\n// specifier — `wrapRequestHandler` must load on runtimes without `nodejs_compat`, and the\n// module-graph test forbids any `node:` import reachable from it.\ninterface PublishableTracingChannel {\n start: { publish(ctx: Ctx): void };\n end: { publish(ctx: Ctx): void };\n error: { publish(ctx: Ctx): void };\n}\n\ninterface DeferredChannelEvent {\n channel: PublishableTracingChannel;\n ctx: Ctx;\n hadError: boolean;\n}\n\nconst deferred: DeferredChannelEvent[] = [];\nconst DEFERRED = Symbol('sentryOrchestrionDeferred');\n\n/** workerd's global-scope guard is the only error we degrade on; anything else is a real fault. */\nexport function isGlobalScopeError(error: unknown): boolean {\n return error instanceof Error && /within global scope/.test(error.message);\n}\n\n/** Queue a channel event that could not be published now, at most once per context object. */\nexport function deferChannelEvent(channel: PublishableTracingChannel, ctx: Ctx): void {\n if ((ctx as Record<symbol, unknown>)[DEFERRED]) {\n return;\n }\n (ctx as Record<symbol, unknown>)[DEFERRED] = true;\n deferred.push({ channel, ctx, hadError: 'error' in ctx });\n}\n\n/**\n * Emit every deferred channel event via the real channel. Called at the top of the request\n * handler, after `init()` has subscribed. Uses bare `start`/`end` publish (never `runStores`),\n * so no `bindStore` producer runs and no span is parented to this request — only the plain\n * subscribers (the instance patchers) fire. Idempotent: it drains the queue, so later requests\n * and re-entrant calls are no-ops.\n */\nexport function flushDeferredChannelEvents(): void {\n if (deferred.length === 0) {\n return;\n }\n const pending = deferred.splice(0, deferred.length);\n for (const { channel, ctx, hadError } of pending) {\n try {\n channel.start.publish(ctx);\n if (hadError) {\n channel.error.publish(ctx);\n }\n channel.end.publish(ctx);\n } catch (error) {\n DEBUG_BUILD && debug.warn('[orchestrion] failed to emit a deferred channel event', error);\n }\n }\n}\n"],"names":["DEBUG_BUILD","debug"],"mappings":";;;;;AAkCA,MAAM,WAAmC,EAAC;AAC1C,MAAM,QAAA,0BAAkB,2BAA2B,CAAA;AAG5C,SAAS,mBAAmB,KAAA,EAAyB;AAC1D,EAAA,OAAO,KAAA,YAAiB,KAAA,IAAS,qBAAA,CAAsB,IAAA,CAAK,MAAM,OAAO,CAAA;AAC3E;AAGO,SAAS,iBAAA,CAAkB,SAAoC,GAAA,EAAgB;AACpF,EAAA,IAAK,GAAA,CAAgC,QAAQ,CAAA,EAAG;AAC9C,IAAA;AAAA,EACF;AACA,EAAC,GAAA,CAAgC,QAAQ,CAAA,GAAI,IAAA;AAC7C,EAAA,QAAA,CAAS,KAAK,EAAE,OAAA,EAAS,KAAK,QAAA,EAAU,OAAA,IAAW,KAAK,CAAA;AAC1D;AASO,SAAS,0BAAA,GAAmC;AACjD,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,IAAA;AAAA,EACF;AACA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,CAAA,EAAG,SAAS,MAAM,CAAA;AAClD,EAAA,KAAA,MAAW,EAAE,OAAA,EAAS,GAAA,EAAK,QAAA,MAAc,OAAA,EAAS;AAChD,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,KAAA,CAAM,QAAQ,GAAG,CAAA;AACzB,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAA,CAAQ,KAAA,CAAM,QAAQ,GAAG,CAAA;AAAA,MAC3B;AACA,MAAA,OAAA,CAAQ,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAA,IACzB,SAAS,KAAA,EAAO;AACd,MAAAA,sBAAA,IAAeC,UAAA,CAAM,IAAA,CAAK,uDAAA,EAAyD,KAAK,CAAA;AAAA,IAC1F;AAAA,EACF;AACF;;;;;;"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
2
|
+
|
|
3
|
+
const realDc = require('node:diagnostics_channel');
|
|
4
|
+
const orchestrionDeferredChannels = require('./orchestrion-deferred-channels.js');
|
|
5
|
+
|
|
6
|
+
const cache = /* @__PURE__ */ new Map();
|
|
7
|
+
function channelHasSubscribers(ch) {
|
|
8
|
+
const value = ch.hasSubscribers;
|
|
9
|
+
return typeof value === "function" ? Boolean(value.call(ch)) : Boolean(value);
|
|
10
|
+
}
|
|
11
|
+
function wrapSubChannel(tracing, real) {
|
|
12
|
+
return {
|
|
13
|
+
name: real.name,
|
|
14
|
+
// A method (not a getter) so it reads truthy as a property in the emit guard *and* is callable,
|
|
15
|
+
// matching workerd's native shape. Forced `true`: on Cloudflare a channel is only injected for a
|
|
16
|
+
// bundled integration, so the wrapper's no-subscriber short-circuit buys nothing — and disabling
|
|
17
|
+
// it is what lets the wrapper run (and reach us) at module scope before `init()` has subscribed.
|
|
18
|
+
hasSubscribers() {
|
|
19
|
+
return true;
|
|
20
|
+
},
|
|
21
|
+
publish(ctx) {
|
|
22
|
+
const hadSubscribers = channelHasSubscribers(real);
|
|
23
|
+
try {
|
|
24
|
+
real.publish(ctx);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (!orchestrionDeferredChannels.isGlobalScopeError(error)) {
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
if (!hadSubscribers) {
|
|
30
|
+
orchestrionDeferredChannels.deferChannelEvent(tracing, ctx);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
runStores(ctx, fn, ...rest) {
|
|
35
|
+
try {
|
|
36
|
+
return real.runStores(ctx, fn, ...rest);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (!orchestrionDeferredChannels.isGlobalScopeError(error)) {
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
return fn();
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
subscribe: real.subscribe.bind(real),
|
|
45
|
+
unsubscribe: real.unsubscribe.bind(real),
|
|
46
|
+
bindStore: real.bindStore.bind(real),
|
|
47
|
+
unbindStore: real.unbindStore.bind(real)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function tracingChannel(name) {
|
|
51
|
+
const cached = cache.get(name);
|
|
52
|
+
if (cached) {
|
|
53
|
+
return cached;
|
|
54
|
+
}
|
|
55
|
+
const real = realDc.tracingChannel(name);
|
|
56
|
+
const facade = {
|
|
57
|
+
start: wrapSubChannel(real, real.start),
|
|
58
|
+
end: wrapSubChannel(real, real.end),
|
|
59
|
+
asyncStart: wrapSubChannel(real, real.asyncStart),
|
|
60
|
+
asyncEnd: wrapSubChannel(real, real.asyncEnd),
|
|
61
|
+
error: wrapSubChannel(real, real.error),
|
|
62
|
+
// Iterator (`:next`) channels call these on the tracingChannel itself; delegate to the real
|
|
63
|
+
// implementation (they only run in-request, where publish/runStores are allowed).
|
|
64
|
+
traceSync: real.traceSync.bind(real),
|
|
65
|
+
tracePromise: real.tracePromise.bind(real),
|
|
66
|
+
traceCallback: real.traceCallback.bind(real),
|
|
67
|
+
subscribe: real.subscribe.bind(real),
|
|
68
|
+
unsubscribe: real.unsubscribe.bind(real)
|
|
69
|
+
};
|
|
70
|
+
cache.set(name, facade);
|
|
71
|
+
return facade;
|
|
72
|
+
}
|
|
73
|
+
const channel = realDc.channel;
|
|
74
|
+
const subscribe = realDc.subscribe;
|
|
75
|
+
const unsubscribe = realDc.unsubscribe;
|
|
76
|
+
const orchestrionDiagnosticsChannel = { tracingChannel, channel, subscribe, unsubscribe };
|
|
77
|
+
|
|
78
|
+
exports.channel = channel;
|
|
79
|
+
exports.default = orchestrionDiagnosticsChannel;
|
|
80
|
+
exports.subscribe = subscribe;
|
|
81
|
+
exports.tracingChannel = tracingChannel;
|
|
82
|
+
exports.unsubscribe = unsubscribe;
|
|
83
|
+
//# sourceMappingURL=orchestrion-diagnostics-channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrion-diagnostics-channel.js","sources":["../../../src/orchestrion-diagnostics-channel.ts"],"sourcesContent":["/**\n * A workerd-safe `diagnostics_channel` façade for the orchestrion EMIT side, and the\n * `dcModule` target for the Cloudflare orchestrion build (see `vite/index.ts`): orchestrion's\n * transformed code imports `tracingChannel` from here (its default export) instead of\n * `node:diagnostics_channel`.\n *\n * On workerd, `channel.publish()` and `channel.runStores()` throw at module/global scope\n * (\"Disallowed operation called within global scope …\"); only inside a request handler do they\n * work. `subscribe` and channel creation are fine anywhere. Orchestrion's transformed code emits\n * `start.runStores(...)` / `end.publish(...)` at each wrapped call site, so a library\n * instantiated at module scope (`const app = new Hono()`) throws the moment it is wrapped — or,\n * if no subscriber exists yet, is skipped by the wrapper's `if (!hasSubscribers) return\n * __apm$traced()` short-circuit and never instrumented.\n *\n * This façade delegates to the real `node:diagnostics_channel` singletons — so subscribers, which\n * keep subscribing through `node:diagnostics_channel`, are reached unchanged — and changes two\n * things:\n *\n * 1. `hasSubscribers` always reports `true`, so the wrapper never short-circuits. On Cloudflare a\n * channel is only injected for an integration that is actually bundled, so the short-circuit\n * buys nothing — and disabling it is what lets the wrapper run (and reach us) at module scope,\n * before the per-request cached `init()` has subscribed.\n * 2. When a delegated `publish`/`runStores` throws the global-scope error, the event is queued via\n * {@link deferChannelEvent} instead. {@link flushDeferredChannelEvents}, called at the top of\n * the request handler after `init()`, emits it via the real channel — now inside a request,\n * where publish works.\n *\n * In a request handler nothing throws, so every call is a transparent pass-through to the real\n * channel: lifecycle channels (spans, context binding) behave exactly as on Node.\n */\nimport * as realDc from 'node:diagnostics_channel';\nimport { deferChannelEvent, isGlobalScopeError } from './orchestrion-deferred-channels';\n\ntype Ctx = Record<string, unknown>;\n\n// One façade per channel name (node's `tracingChannel` is itself a per-name singleton), built\n// once when the transformed module declares `const CH = tracingChannel(name)`.\nconst cache = new Map<string, realDc.TracingChannel>();\n\n// `Channel.hasSubscribers` is a getter on Node but a method on workerd — normalize both to a\n// boolean. (This shape difference is also why the emit wrapper never short-circuits on workerd:\n// its `if (!ch.start.hasSubscribers)` guard reads a truthy method reference.)\nfunction channelHasSubscribers(ch: realDc.Channel): boolean {\n const value = (ch as { hasSubscribers: unknown }).hasSubscribers;\n return typeof value === 'function' ? Boolean((value as () => unknown).call(ch)) : Boolean(value);\n}\n\nfunction wrapSubChannel(tracing: realDc.TracingChannel, real: realDc.Channel): realDc.Channel {\n return {\n name: real.name,\n // A method (not a getter) so it reads truthy as a property in the emit guard *and* is callable,\n // matching workerd's native shape. Forced `true`: on Cloudflare a channel is only injected for a\n // bundled integration, so the wrapper's no-subscriber short-circuit buys nothing — and disabling\n // it is what lets the wrapper run (and reach us) at module scope before `init()` has subscribed.\n hasSubscribers(): boolean {\n return true;\n },\n publish(ctx: Ctx): void {\n // Snapshot subscriber presence before publishing — it decides whether to defer if the\n // global-scope error fires below.\n const hadSubscribers = channelHasSubscribers(real);\n try {\n real.publish(ctx);\n } catch (error) {\n if (!isGlobalScopeError(error)) {\n throw error;\n }\n // We're at module scope (workerd throws here even with no subscribers). If someone was\n // already subscribed — top-level `Sentry.init()` — workerd delivered to them before\n // throwing, so they got it exactly once; don't defer. Otherwise — the common per-request\n // cached-init case — nobody received it, so defer for a subscriber that registers later\n // (at `init()`), which then gets it exactly once. In a request `publish` doesn't throw,\n // so this path never defers a normal in-request event.\n if (!hadSubscribers) {\n deferChannelEvent(tracing, ctx);\n }\n }\n },\n runStores(ctx: Ctx, fn: (...args: unknown[]) => unknown, ...rest: unknown[]): unknown {\n try {\n return real.runStores(ctx, fn, ...rest);\n } catch (error) {\n if (!isGlobalScopeError(error)) {\n throw error;\n }\n // publish() is gated too, so the store can't be established — just run the wrapped call\n // so its return value (e.g. the constructed instance) is produced now. Its own\n // `end.publish` runs back through this façade and is deferred.\n return fn();\n }\n },\n subscribe: real.subscribe.bind(real),\n unsubscribe: real.unsubscribe.bind(real),\n bindStore: real.bindStore.bind(real),\n unbindStore: real.unbindStore.bind(real),\n } as unknown as realDc.Channel;\n}\n\nexport function tracingChannel<T = Ctx>(name: string): realDc.TracingChannel<T> {\n const cached = cache.get(name);\n if (cached) {\n return cached;\n }\n\n const real = realDc.tracingChannel(name);\n const facade = {\n start: wrapSubChannel(real, real.start),\n end: wrapSubChannel(real, real.end),\n asyncStart: wrapSubChannel(real, real.asyncStart),\n asyncEnd: wrapSubChannel(real, real.asyncEnd),\n error: wrapSubChannel(real, real.error),\n // Iterator (`:next`) channels call these on the tracingChannel itself; delegate to the real\n // implementation (they only run in-request, where publish/runStores are allowed).\n traceSync: real.traceSync.bind(real),\n tracePromise: real.tracePromise.bind(real),\n traceCallback: real.traceCallback.bind(real),\n subscribe: real.subscribe.bind(real),\n unsubscribe: real.unsubscribe.bind(real),\n } as unknown as realDc.TracingChannel<T>;\n\n cache.set(name, facade);\n return facade;\n}\n\nexport const channel = realDc.channel;\nexport const subscribe = realDc.subscribe;\nexport const unsubscribe = realDc.unsubscribe;\n\n// Orchestrion's emit imports the default and destructures `tracingChannel`.\nexport default { tracingChannel, channel, subscribe, unsubscribe };\n"],"names":["isGlobalScopeError","deferChannelEvent"],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const node_module = require('node:module');
|
|
4
|
+
const node_path = require('node:path');
|
|
5
|
+
const MagicString = require('magic-string');
|
|
6
|
+
|
|
7
|
+
const PROVIDER_IDENTIFIER = "__SENTRY_FLUE_RUNTIME__";
|
|
8
|
+
const FLUE_MODULE = "@flue/runtime";
|
|
9
|
+
const FLUE_INTEGRATION_ID = /@sentry\/server-utils\/build\/esm\/integrations\/flue\.js$/;
|
|
10
|
+
function isFlueIntegrationModuleId(id) {
|
|
11
|
+
const normalizedId = id.replace(/\\/g, "/").replace(/[?#].*$/, "");
|
|
12
|
+
return FLUE_INTEGRATION_ID.test(normalizedId);
|
|
13
|
+
}
|
|
14
|
+
function sentryFlueRuntimeProviderPlugin() {
|
|
15
|
+
let providerSnippet;
|
|
16
|
+
return {
|
|
17
|
+
name: "sentry-cloudflare-flue-runtime-provider",
|
|
18
|
+
configResolved(config) {
|
|
19
|
+
try {
|
|
20
|
+
node_module.createRequire(node_path.resolve(config.root, "noop.js")).resolve(FLUE_MODULE);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
const code = error?.code;
|
|
23
|
+
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
providerSnippet = `import * as ${PROVIDER_IDENTIFIER} from '${FLUE_MODULE}';
|
|
28
|
+
(globalThis.__SENTRY_ORCHESTRION__ = globalThis.__SENTRY_ORCHESTRION__ || {});
|
|
29
|
+
(globalThis.__SENTRY_ORCHESTRION__.providedModules = globalThis.__SENTRY_ORCHESTRION__.providedModules || {});
|
|
30
|
+
Object.defineProperty(globalThis.__SENTRY_ORCHESTRION__.providedModules, '${FLUE_MODULE}', { configurable: true, enumerable: true, get() { return ${PROVIDER_IDENTIFIER}; } });
|
|
31
|
+
`;
|
|
32
|
+
},
|
|
33
|
+
transform(code, id) {
|
|
34
|
+
if (!providerSnippet || !isFlueIntegrationModuleId(id) || code.includes(PROVIDER_IDENTIFIER)) return void 0;
|
|
35
|
+
const ms = new MagicString.default(code);
|
|
36
|
+
ms.prepend(providerSnippet);
|
|
37
|
+
return { code: ms.toString(), map: ms.generateMap({ hires: true }) };
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
exports.isFlueIntegrationModuleId = isFlueIntegrationModuleId;
|
|
43
|
+
exports.sentryFlueRuntimeProviderPlugin = sentryFlueRuntimeProviderPlugin;
|
|
44
|
+
//# sourceMappingURL=flueRuntime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flueRuntime.js","sources":["../../../../src/vite/flueRuntime.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\nimport MagicString from 'magic-string';\n\n// Namespace binding the injected provider import uses; read back by the integration\n// off the global marker.\nconst PROVIDER_IDENTIFIER = '__SENTRY_FLUE_RUNTIME__';\n\nconst FLUE_MODULE = '@flue/runtime';\n\n// The bundled `@sentry/server-utils` Flue integration module (ESM build — the only one a\n// worker loads). It reads `@flue/runtime` off the global marker this provider populates,\n// because `instrument()` registers into module-scope state no channel payload can carry.\nconst FLUE_INTEGRATION_ID = /@sentry\\/server-utils\\/build\\/esm\\/integrations\\/flue\\.js$/;\n\n/** Whether `id` is the Sentry Flue integration module the provider injects into. */\nexport function isFlueIntegrationModuleId(id: string): boolean {\n const normalizedId = id.replace(/\\\\/g, '/').replace(/[?#].*$/, '');\n return FLUE_INTEGRATION_ID.test(normalizedId);\n}\n\n/**\n * Splices a static `import * as … from '@flue/runtime'` into Sentry's own Flue integration module\n * and exposes the namespace on the global orchestrion marker.\n *\n * Flue is registered rather than patched — `instrument()` writes into module-scope state — so\n * instrumenting it needs that module's own binding, and no channel payload carries one. On Node the\n * user passes it by calling `instrument()` themselves; a bundled worker has no `node_modules` to\n * resolve from, so it is supplied at build time instead.\n */\nexport function sentryFlueRuntimeProviderPlugin(): {\n name: string;\n configResolved(config: { root: string }): void;\n transform(code: string, id: string): { code: string; map: ReturnType<MagicString['generateMap']> } | undefined;\n} {\n let providerSnippet: string | undefined;\n\n return {\n name: 'sentry-cloudflare-flue-runtime-provider',\n\n configResolved(config: { root: string }): void {\n // Build-time only; never ships to the worker. Probed with CJS resolution, which an ESM-only\n // `@flue/runtime` fails with `ERR_PACKAGE_PATH_NOT_EXPORTED` — so only a module-not-found\n // counts as absent, and any other failure still injects and lets Vite report it. Not\n // `import.meta.resolve`: `parentURL` is ignored without a flag, and it is absent from the\n // CJS build.\n try {\n createRequire(resolve(config.root, 'noop.js')).resolve(FLUE_MODULE);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND') {\n return;\n }\n }\n // A getter where Mastra assigns: the bundler may evaluate Sentry's module before\n // `@flue/runtime` is initialized, and assigning there would store `undefined`.\n providerSnippet =\n `import * as ${PROVIDER_IDENTIFIER} from '${FLUE_MODULE}';\\n` +\n '(globalThis.__SENTRY_ORCHESTRION__ = globalThis.__SENTRY_ORCHESTRION__ || {});\\n' +\n '(globalThis.__SENTRY_ORCHESTRION__.providedModules = globalThis.__SENTRY_ORCHESTRION__.providedModules || {});\\n' +\n `Object.defineProperty(globalThis.__SENTRY_ORCHESTRION__.providedModules, '${FLUE_MODULE}', ` +\n `{ configurable: true, enumerable: true, get() { return ${PROVIDER_IDENTIFIER}; } });\\n`;\n },\n\n transform(code: string, id: string): { code: string; map: ReturnType<MagicString['generateMap']> } | undefined {\n // `code.includes` keeps this idempotent: a second pass over already-injected output would\n // otherwise emit a duplicate `import * as` binding, which is a syntax error.\n if (!providerSnippet || !isFlueIntegrationModuleId(id) || code.includes(PROVIDER_IDENTIFIER)) return undefined;\n\n const ms = new MagicString(code);\n ms.prepend(providerSnippet);\n return { code: ms.toString(), map: ms.generateMap({ hires: true }) };\n },\n };\n}\n"],"names":["createRequire","resolve","MagicString"],"mappings":";;;;;;AAMA,MAAM,mBAAA,GAAsB,yBAAA;AAE5B,MAAM,WAAA,GAAc,eAAA;AAKpB,MAAM,mBAAA,GAAsB,4DAAA;AAGrB,SAAS,0BAA0B,EAAA,EAAqB;AAC7D,EAAA,MAAM,YAAA,GAAe,GAAG,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,WAAW,EAAE,CAAA;AACjE,EAAA,OAAO,mBAAA,CAAoB,KAAK,YAAY,CAAA;AAC9C;AAWO,SAAS,+BAAA,GAId;AACA,EAAA,IAAI,eAAA;AAEJ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,yCAAA;AAAA,IAEN,eAAe,MAAA,EAAgC;AAM7C,MAAA,IAAI;AACF,QAAAA,yBAAA,CAAcC,kBAAQ,MAAA,CAAO,IAAA,EAAM,SAAS,CAAC,CAAA,CAAE,QAAQ,WAAW,CAAA;AAAA,MACpE,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,OAAQ,KAAA,EAA6C,IAAA;AAC3D,QAAA,IAAI,IAAA,KAAS,kBAAA,IAAsB,IAAA,KAAS,sBAAA,EAAwB;AAClE,UAAA;AAAA,QACF;AAAA,MACF;AAGA,MAAA,eAAA,GACE,CAAA,YAAA,EAAe,mBAAmB,CAAA,OAAA,EAAU,WAAW,CAAA;AAAA;AAAA;AAAA,0EAAA,EAGsB,WAAW,6DAC9B,mBAAmB,CAAA;AAAA,CAAA;AAAA,IACjF,CAAA;AAAA,IAEA,SAAA,CAAU,MAAc,EAAA,EAAuF;AAG7G,MAAA,IAAI,CAAC,eAAA,IAAmB,CAAC,yBAAA,CAA0B,EAAE,KAAK,IAAA,CAAK,QAAA,CAAS,mBAAmB,CAAA,EAAG,OAAO,MAAA;AAErG,MAAA,MAAM,EAAA,GAAK,IAAIC,mBAAA,CAAY,IAAI,CAAA;AAC/B,MAAA,EAAA,CAAG,QAAQ,eAAe,CAAA;AAC1B,MAAA,OAAO,EAAE,IAAA,EAAM,EAAA,CAAG,QAAA,EAAS,EAAG,GAAA,EAAK,EAAA,CAAG,WAAA,CAAY,EAAE,KAAA,EAAO,IAAA,EAAM,CAAA,EAAE;AAAA,IACrE;AAAA,GACF;AACF;;;;;"}
|
|
@@ -2,12 +2,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const vite = require('@sentry/server-utils/orchestrion/vite');
|
|
4
4
|
const autoInstrument = require('./autoInstrument.js');
|
|
5
|
+
const flueRuntime = require('./flueRuntime.js');
|
|
6
|
+
const mastraObservability = require('./mastraObservability.js');
|
|
5
7
|
|
|
6
8
|
function sentryCloudflareVitePlugin(options = {}) {
|
|
7
9
|
return [
|
|
8
10
|
vite.sentryOrchestrionPlugin({
|
|
9
|
-
buildTimeInstrumentation: options.buildTimeInstrumentation
|
|
11
|
+
buildTimeInstrumentation: options.buildTimeInstrumentation,
|
|
12
|
+
// Route the injected `tracingChannel` imports through the workerd-safe façade so a
|
|
13
|
+
// dependency wrapped at module scope (`const app = new Hono()`) doesn't throw on workerd.
|
|
14
|
+
dcModule: "@sentry/cloudflare/orchestrion-diagnostics-channel"
|
|
10
15
|
}),
|
|
16
|
+
mastraObservability.sentryMastraObservabilityProviderPlugin(),
|
|
17
|
+
flueRuntime.sentryFlueRuntimeProviderPlugin(),
|
|
11
18
|
...options.autoInstrumentation !== false ? [autoInstrument.sentryCloudflareAutoInstrumentPlugin({ wranglerConfigPath: options.wranglerConfigPath })] : []
|
|
12
19
|
];
|
|
13
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/vite/index.ts"],"sourcesContent":["// Published ESM-only via the `@sentry/cloudflare/vite` subpath export:\n// `@sentry/server-utils/orchestrion/vite` exposes no `require` condition, so a\n// CJS entry here would fail at resolution time (ERR_PACKAGE_PATH_NOT_EXPORTED).\n// The CJS rollup variant still emits this file, but `package.json` doesn't\n// expose it — same setup as `@sentry/server-utils/orchestrion/vite` itself.\nimport { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';\nimport { sentryCloudflareAutoInstrumentPlugin } from './autoInstrument';\n\n/**\n * Options for {@link sentryCloudflareVitePlugin}.\n */\nexport interface SentryCloudflareVitePluginOptions {\n /**\n * Path to the wrangler config, relative to the Vite root (or absolute).\n * Set this when your config doesn't use a default name — e.g. when you\n * pass `configPath: './wrangler.agent.jsonc'` to `@cloudflare/vite-plugin`,\n * which the Sentry plugin cannot see. When set, only this file is read\n * (no default-name probing), and a warning is emitted if it is missing or\n * unparseable.\n *\n * @default undefined (probes `wrangler.json`, `wrangler.jsonc`, `wrangler.toml` at the Vite root)\n */\n wranglerConfigPath?: string;\n /**\n * Build-time automatic instrumentation of supported dependencies (e.g.\n * database clients like `mysql`) so the Sentry Cloudflare SDK can trace them\n * without monkey-patching, which wouldn't work in workerd anyway.\n *\n * When enabled, the plugin injects `diagnostics_channel.tracingChannel` calls\n * into the bundled packages and, next to each, a snippet that registers the\n * matching Sentry channel-subscriber factory on the global marker, which the\n * SDK picks up in `Sentry.withSentry()`. Both `vite build` and `vite dev` are\n * instrumented. Set to `false` to opt out.\n *\n * @default true\n */\n buildTimeInstrumentation?: boolean;\n /**\n * Automatically wraps your Worker at build time so you don't have to edit\n * your entry: the plugin reads your wrangler config, wraps the default\n * export with `Sentry.withSentry()` (sourcing options from a co-located\n * `instrument.*` file, falling back to env), and wraps any configured\n * Durable Object class with `instrumentDurableObjectWithSentry`. Both\n * `vite build` and `vite dev` are instrumented. Already-wrapped entries are\n * left alone, so this is safe alongside manual instrumentation. Set to\n * `false` to opt out.\n *\n * The plugin also adds the bindings that resolve to the wrapped classes (this worker's own\n * Durable Objects and self service bindings) to `rpcTracePropagationBindings`. Bindings to\n * other workers stay opt-in, their receivers may not run Sentry.\n *\n * @default true\n */\n autoInstrumentation?: boolean;\n}\n\n/**\n * Sentry Vite plugin for Cloudflare Workers.\n *\n * Add this plugin to your Vite configuration to enable additional Sentry\n * instrumentation for Cloudflare Workers built with Vite.\n *\n * By default, the plugin\n * - build-time instruments supported dependencies (such as database clients) so\n * they are traced without changing your application code — opt out with\n * `buildTimeInstrumentation: false`, and\n * - wraps your Worker entry (and any Durable Object, Workflow or\n * WorkerEntrypoint class in your wrangler config) with the matching Sentry\n * helper — opt out with `autoInstrumentation: false` and call\n * `Sentry.withSentry()` yourself.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { cloudflare } from '@cloudflare/vite-plugin';\n * import { sentryCloudflareVitePlugin } from '@sentry/cloudflare/vite';\n * import { defineConfig } from 'vite';\n *\n * export default defineConfig({\n * plugins: [cloudflare(), sentryCloudflareVitePlugin()],\n * });\n * ```\n */\nexport function sentryCloudflareVitePlugin(options: SentryCloudflareVitePluginOptions = {}): Array<{ name: string }> {\n return [\n sentryOrchestrionPlugin({\n buildTimeInstrumentation: options.buildTimeInstrumentation,\n }),\n ...(options.autoInstrumentation !== false\n ? [sentryCloudflareAutoInstrumentPlugin({ wranglerConfigPath: options.wranglerConfigPath })]\n : []),\n ];\n}\n"],"names":["sentryOrchestrionPlugin","sentryCloudflareAutoInstrumentPlugin"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/vite/index.ts"],"sourcesContent":["// Published ESM-only via the `@sentry/cloudflare/vite` subpath export:\n// `@sentry/server-utils/orchestrion/vite` exposes no `require` condition, so a\n// CJS entry here would fail at resolution time (ERR_PACKAGE_PATH_NOT_EXPORTED).\n// The CJS rollup variant still emits this file, but `package.json` doesn't\n// expose it — same setup as `@sentry/server-utils/orchestrion/vite` itself.\nimport { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';\nimport { sentryCloudflareAutoInstrumentPlugin } from './autoInstrument';\nimport { sentryFlueRuntimeProviderPlugin } from './flueRuntime';\nimport { sentryMastraObservabilityProviderPlugin } from './mastraObservability';\n\n/**\n * Options for {@link sentryCloudflareVitePlugin}.\n */\nexport interface SentryCloudflareVitePluginOptions {\n /**\n * Path to the wrangler config, relative to the Vite root (or absolute).\n * Set this when your config doesn't use a default name — e.g. when you\n * pass `configPath: './wrangler.agent.jsonc'` to `@cloudflare/vite-plugin`,\n * which the Sentry plugin cannot see. When set, only this file is read\n * (no default-name probing), and a warning is emitted if it is missing or\n * unparseable.\n *\n * @default undefined (probes `wrangler.json`, `wrangler.jsonc`, `wrangler.toml` at the Vite root)\n */\n wranglerConfigPath?: string;\n /**\n * Build-time automatic instrumentation of supported dependencies (e.g.\n * database clients like `mysql`) so the Sentry Cloudflare SDK can trace them\n * without monkey-patching, which wouldn't work in workerd anyway.\n *\n * When enabled, the plugin injects `diagnostics_channel.tracingChannel` calls\n * into the bundled packages and, next to each, a snippet that registers the\n * matching Sentry channel-subscriber factory on the global marker, which the\n * SDK picks up in `Sentry.withSentry()`. Both `vite build` and `vite dev` are\n * instrumented. Set to `false` to opt out.\n *\n * @default true\n */\n buildTimeInstrumentation?: boolean;\n /**\n * Automatically wraps your Worker at build time so you don't have to edit\n * your entry: the plugin reads your wrangler config, wraps the default\n * export with `Sentry.withSentry()` (sourcing options from a co-located\n * `instrument.*` file, falling back to env), and wraps any configured\n * Durable Object class with `instrumentDurableObjectWithSentry`. Both\n * `vite build` and `vite dev` are instrumented. Already-wrapped entries are\n * left alone, so this is safe alongside manual instrumentation. Set to\n * `false` to opt out.\n *\n * The plugin also adds the bindings that resolve to the wrapped classes (this worker's own\n * Durable Objects and self service bindings) to `rpcTracePropagationBindings`. Bindings to\n * other workers stay opt-in, their receivers may not run Sentry.\n *\n * @default true\n */\n autoInstrumentation?: boolean;\n}\n\n/**\n * Sentry Vite plugin for Cloudflare Workers.\n *\n * Add this plugin to your Vite configuration to enable additional Sentry\n * instrumentation for Cloudflare Workers built with Vite.\n *\n * By default, the plugin\n * - build-time instruments supported dependencies (such as database clients) so\n * they are traced without changing your application code — opt out with\n * `buildTimeInstrumentation: false`, and\n * - wraps your Worker entry (and any Durable Object, Workflow or\n * WorkerEntrypoint class in your wrangler config) with the matching Sentry\n * helper — opt out with `autoInstrumentation: false` and call\n * `Sentry.withSentry()` yourself.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { cloudflare } from '@cloudflare/vite-plugin';\n * import { sentryCloudflareVitePlugin } from '@sentry/cloudflare/vite';\n * import { defineConfig } from 'vite';\n *\n * export default defineConfig({\n * plugins: [cloudflare(), sentryCloudflareVitePlugin()],\n * });\n * ```\n */\nexport function sentryCloudflareVitePlugin(options: SentryCloudflareVitePluginOptions = {}): Array<{ name: string }> {\n return [\n sentryOrchestrionPlugin({\n buildTimeInstrumentation: options.buildTimeInstrumentation,\n // Route the injected `tracingChannel` imports through the workerd-safe façade so a\n // dependency wrapped at module scope (`const app = new Hono()`) doesn't throw on workerd.\n dcModule: '@sentry/cloudflare/orchestrion-diagnostics-channel',\n }),\n sentryMastraObservabilityProviderPlugin(),\n sentryFlueRuntimeProviderPlugin(),\n ...(options.autoInstrumentation !== false\n ? [sentryCloudflareAutoInstrumentPlugin({ wranglerConfigPath: options.wranglerConfigPath })]\n : []),\n ];\n}\n"],"names":["sentryOrchestrionPlugin","sentryMastraObservabilityProviderPlugin","sentryFlueRuntimeProviderPlugin","sentryCloudflareAutoInstrumentPlugin"],"mappings":";;;;;;;AAqFO,SAAS,0BAAA,CAA2B,OAAA,GAA6C,EAAC,EAA4B;AACnH,EAAA,OAAO;AAAA,IACLA,4BAAA,CAAwB;AAAA,MACtB,0BAA0B,OAAA,CAAQ,wBAAA;AAAA;AAAA;AAAA,MAGlC,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACDC,2DAAA,EAAwC;AAAA,IACxCC,2CAAA,EAAgC;AAAA,IAChC,GAAI,OAAA,CAAQ,mBAAA,KAAwB,KAAA,GAChC,CAACC,mDAAA,CAAqC,EAAE,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,EAAoB,CAAC,IACzF;AAAC,GACP;AACF;;;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const node_module = require('node:module');
|
|
4
|
+
const node_path = require('node:path');
|
|
5
|
+
const MagicString = require('magic-string');
|
|
6
|
+
|
|
7
|
+
const PROVIDER_IDENTIFIER = "__SENTRY_MASTRA_OBSERVABILITY__";
|
|
8
|
+
const MASTRA_INTEGRATION_ID = /@sentry\/server-utils\/build\/esm\/integrations\/mastra\.js$/;
|
|
9
|
+
function isMastraIntegrationModuleId(id) {
|
|
10
|
+
const normalizedId = id.replace(/\\/g, "/").replace(/[?#].*$/, "");
|
|
11
|
+
return MASTRA_INTEGRATION_ID.test(normalizedId);
|
|
12
|
+
}
|
|
13
|
+
function sentryMastraObservabilityProviderPlugin() {
|
|
14
|
+
let providerSnippet;
|
|
15
|
+
return {
|
|
16
|
+
name: "sentry-cloudflare-mastra-observability-provider",
|
|
17
|
+
configResolved(config) {
|
|
18
|
+
try {
|
|
19
|
+
node_module.createRequire(node_path.resolve(config.root, "noop.js")).resolve("@mastra/observability");
|
|
20
|
+
} catch {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
providerSnippet = `import * as ${PROVIDER_IDENTIFIER} from '@mastra/observability';
|
|
24
|
+
(globalThis.__SENTRY_ORCHESTRION__ = globalThis.__SENTRY_ORCHESTRION__ || {});
|
|
25
|
+
(globalThis.__SENTRY_ORCHESTRION__.providedModules = globalThis.__SENTRY_ORCHESTRION__.providedModules || {})['@mastra/observability'] = ${PROVIDER_IDENTIFIER};
|
|
26
|
+
`;
|
|
27
|
+
},
|
|
28
|
+
transform(code, id) {
|
|
29
|
+
if (!providerSnippet || !isMastraIntegrationModuleId(id)) return void 0;
|
|
30
|
+
const ms = new MagicString.default(code);
|
|
31
|
+
ms.prepend(providerSnippet);
|
|
32
|
+
return { code: ms.toString(), map: ms.generateMap({ hires: true }) };
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
exports.isMastraIntegrationModuleId = isMastraIntegrationModuleId;
|
|
38
|
+
exports.sentryMastraObservabilityProviderPlugin = sentryMastraObservabilityProviderPlugin;
|
|
39
|
+
//# sourceMappingURL=mastraObservability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mastraObservability.js","sources":["../../../../src/vite/mastraObservability.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\nimport MagicString from 'magic-string';\n\n// Namespace binding the injected provider import uses; read back by the integration\n// off the global marker.\nconst PROVIDER_IDENTIFIER = '__SENTRY_MASTRA_OBSERVABILITY__';\n\n// The bundled `@sentry/server-utils` Mastra integration module (ESM build — the only\n// one a worker loads). Its `loadMastraObservability` reads `@mastra/observability` off\n// the global marker this provider populates, instead of `createRequire`, which cannot\n// resolve a package inside a bundled worker.\nconst MASTRA_INTEGRATION_ID = /@sentry\\/server-utils\\/build\\/esm\\/integrations\\/mastra\\.js$/;\n\n/** Whether `id` is the Sentry Mastra integration module the provider injects into. */\nexport function isMastraIntegrationModuleId(id: string): boolean {\n const normalizedId = id.replace(/\\\\/g, '/').replace(/[?#].*$/, '');\n return MASTRA_INTEGRATION_ID.test(normalizedId);\n}\n\n/**\n * Splices a static `import * as … from '@mastra/observability'` into Sentry's own\n * Mastra integration module and stashes the namespace on the global orchestrion\n * marker.\n *\n * On Cloudflare the integration cannot `createRequire('@mastra/observability')` to\n * bootstrap Mastra's observability pipeline — there is no on-disk `node_modules` in\n * workerd — so without this the user has to construct and wire up an `Observability`\n * themselves. The import is static (statically analyzable, no lazy `import()`), lands\n * in Sentry's module rather than the user's code, and is only emitted when the package\n * actually resolves; if it is absent, the integration keeps its Node `createRequire`\n * fallback and the marker stays empty.\n */\nexport function sentryMastraObservabilityProviderPlugin(): {\n name: string;\n configResolved(config: { root: string }): void;\n transform(code: string, id: string): { code: string; map: ReturnType<MagicString['generateMap']> } | undefined;\n} {\n let providerSnippet: string | undefined;\n\n return {\n name: 'sentry-cloudflare-mastra-observability-provider',\n\n configResolved(config: { root: string }): void {\n // Resolved at build time (Node), so this `createRequire` never ships to the worker.\n try {\n createRequire(resolve(config.root, 'noop.js')).resolve('@mastra/observability');\n } catch {\n return;\n }\n providerSnippet =\n `import * as ${PROVIDER_IDENTIFIER} from '@mastra/observability';\\n` +\n '(globalThis.__SENTRY_ORCHESTRION__ = globalThis.__SENTRY_ORCHESTRION__ || {});\\n' +\n '(globalThis.__SENTRY_ORCHESTRION__.providedModules = globalThis.__SENTRY_ORCHESTRION__.providedModules || {})' +\n `['@mastra/observability'] = ${PROVIDER_IDENTIFIER};\\n`;\n },\n\n transform(code: string, id: string): { code: string; map: ReturnType<MagicString['generateMap']> } | undefined {\n if (!providerSnippet || !isMastraIntegrationModuleId(id)) return undefined;\n\n const ms = new MagicString(code);\n ms.prepend(providerSnippet);\n return { code: ms.toString(), map: ms.generateMap({ hires: true }) };\n },\n };\n}\n"],"names":["createRequire","resolve","MagicString"],"mappings":";;;;;;AAMA,MAAM,mBAAA,GAAsB,iCAAA;AAM5B,MAAM,qBAAA,GAAwB,8DAAA;AAGvB,SAAS,4BAA4B,EAAA,EAAqB;AAC/D,EAAA,MAAM,YAAA,GAAe,GAAG,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,WAAW,EAAE,CAAA;AACjE,EAAA,OAAO,qBAAA,CAAsB,KAAK,YAAY,CAAA;AAChD;AAeO,SAAS,uCAAA,GAId;AACA,EAAA,IAAI,eAAA;AAEJ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,iDAAA;AAAA,IAEN,eAAe,MAAA,EAAgC;AAE7C,MAAA,IAAI;AACF,QAAAA,yBAAA,CAAcC,kBAAQ,MAAA,CAAO,IAAA,EAAM,SAAS,CAAC,CAAA,CAAE,QAAQ,uBAAuB,CAAA;AAAA,MAChF,CAAA,CAAA,MAAQ;AACN,QAAA;AAAA,MACF;AACA,MAAA,eAAA,GACE,eAAe,mBAAmB,CAAA;AAAA;AAAA,yIAAA,EAGH,mBAAmB,CAAA;AAAA,CAAA;AAAA,IACtD,CAAA;AAAA,IAEA,SAAA,CAAU,MAAc,EAAA,EAAuF;AAC7G,MAAA,IAAI,CAAC,eAAA,IAAmB,CAAC,2BAAA,CAA4B,EAAE,GAAG,OAAO,MAAA;AAEjE,MAAA,MAAM,EAAA,GAAK,IAAIC,mBAAA,CAAY,IAAI,CAAA;AAC/B,MAAA,EAAA,CAAG,QAAQ,eAAe,CAAA;AAC1B,MAAA,OAAO,EAAE,IAAA,EAAM,EAAA,CAAG,QAAA,EAAS,EAAG,GAAA,EAAK,EAAA,CAAG,WAAA,CAAY,EAAE,KAAA,EAAO,IAAA,EAAM,CAAA,EAAE;AAAA,IACrE;AAAA,GACF;AACF;;;;;"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
|
+
const attributes = require('@sentry/conventions/attributes');
|
|
4
|
+
const op = require('@sentry/conventions/op');
|
|
3
5
|
const core = require('@sentry/core');
|
|
4
6
|
const flush = require('./flush.js');
|
|
5
7
|
const instrument = require('./instrument.js');
|
|
@@ -92,12 +94,14 @@ function wrapMethodWithSentry(wrapperOptions, handler, callback, noMark) {
|
|
|
92
94
|
return onRejected(e);
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
|
-
const attributes = wrapperOptions.spanOp ? {
|
|
96
|
-
[
|
|
97
|
-
[
|
|
97
|
+
const attributes$1 = wrapperOptions.spanOp ? {
|
|
98
|
+
[attributes.SENTRY_OP]: wrapperOptions.spanOp,
|
|
99
|
+
[attributes.SENTRY_ORIGIN]: origin,
|
|
100
|
+
// `function` spans are already named like their function name, so we just set `code.function.name` here.
|
|
101
|
+
...wrapperOptions.spanOp === op.FUNCTION && { [attributes.CODE_FUNCTION_NAME]: methodName }
|
|
98
102
|
} : {};
|
|
99
103
|
const executeSpan = () => {
|
|
100
|
-
return core.startSpan({ name: methodName, attributes }, (span) => {
|
|
104
|
+
return core.startSpan({ name: methodName, attributes: attributes$1 }, (span) => {
|
|
101
105
|
if (startNewTrace && storage) {
|
|
102
106
|
const storedContext = traceLinks.getStoredSpanContext(storage, methodName);
|
|
103
107
|
if (storedContext) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrapMethodWithSentry.js","sources":["../../../src/wrapMethodWithSentry.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport type { SerializedTraceData } from '@sentry/core';\nimport {\n isObjectLike,\n captureException,\n continueTrace,\n isThenable,\n type Scope,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startNewTrace as startNewTraceCore,\n startSpan,\n} from '@sentry/core';\nimport type { CloudflareOptions } from './client';\nimport type { ExecutionContextCompat } from './executionContext';\nimport { flushAndDispose, getOriginalWaitUntil } from './flush';\nimport { ensureInstrumented } from './instrument';\nimport { init } from './sdk';\nimport { getInvocationState, getInvocationWaitUntil } from './utils/invocationContext';\nimport { withInvocationIsolationScope } from './utils/invocationScope';\nimport { extractRpcMeta } from './utils/rpcMeta';\nimport { buildSpanLinks, getStoredSpanContext, storeSpanContext } from './utils/traceLinks';\n\n/** Extended DurableObjectState with originalStorage exposed by instrumentContext */\nexport interface InstrumentedDurableObjectState extends DurableObjectState {\n originalStorage?: DurableObjectStorage;\n}\n\n/**\n * Resolves uninstrumented DO storage for the current invocation.\n * Prefer `thisArg.ctx` (the live Durable Object instance) over the context captured at\n * construction time to avoid cross-DO I/O errors in the same isolate.\n */\nfunction resolveOriginalStorage(\n context: ExecutionContext | InstrumentedDurableObjectState | undefined,\n thisArg: unknown,\n): DurableObjectStorage | undefined {\n if (isObjectLike(thisArg) && 'ctx' in thisArg) {\n const doCtx = (thisArg as { ctx: InstrumentedDurableObjectState }).ctx;\n if (doCtx?.originalStorage) {\n return doCtx.originalStorage;\n }\n }\n\n if (context && 'originalStorage' in context && context.originalStorage) {\n return context.originalStorage;\n }\n\n return undefined;\n}\n\ntype MethodWrapperOptions = {\n /**\n * The span name, or a resolver called with the RPC metadata of the current call.\n * Returning `undefined` skips the span and only captures errors.\n */\n spanName?: string | ((rpcMeta: SerializedTraceData | undefined) => string | undefined);\n spanOp?: string;\n options: CloudflareOptions;\n context: ExecutionContext | InstrumentedDurableObjectState;\n /**\n * If true, starts a fresh trace instead of inheriting from a parent trace.\n * Useful for scheduled/independent invocations like alarms.\n *\n * If true, it also stores the current span context and links to the previous invocation's span.\n * Uses Durable Object storage to persist the link. The link is set asynchronously via `span.addLinks()`\n * in a `waitUntil` to avoid blocking.\n *\n * @default false\n */\n startNewTrace?: boolean;\n /**\n * The trace origin identifying which instrumentation created the span, e.g. `auto.faas.cloudflare.durable_object`.\n * Used both as the span's `sentry.origin` attribute and as the `mechanism.type` for captured exceptions.\n */\n origin: string;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type UncheckedMethod = (...args: any[]) => any;\ntype OriginalMethod = UncheckedMethod;\n\n/**\n * Wraps a method with Sentry error tracking and optional tracing.\n * Supports starting new traces and linking to previous invocations via Durable Object storage.\n *\n * @param wrapperOptions - The options for the wrapper.\n * @param handler - The method to wrap.\n * @param callback - The callback to call.\n * @param noMark - Whether to mark the method as instrumented.\n * @returns The wrapped method.\n */\nexport function wrapMethodWithSentry<T extends OriginalMethod>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n noMark?: true,\n): T {\n return ensureInstrumented(\n handler,\n original =>\n new Proxy(original, {\n apply(target, thisArg, rawArgs: Parameters<T>) {\n const { startNewTrace, origin } = wrapperOptions;\n\n // For RPC methods, extract Sentry trace context from the trailing argument.\n // The caller side (instrumentDurableObjectStub / JSRPC proxy) appends it;\n // we strip it here so the user's method never sees it.\n let args = rawArgs;\n let rpcMeta: SerializedTraceData | undefined;\n\n if (wrapperOptions.spanOp === 'rpc') {\n const extracted = extractRpcMeta(rawArgs);\n args = extracted.args;\n rpcMeta = extracted.rpcMeta;\n }\n\n const spanName =\n typeof wrapperOptions.spanName === 'function' ? wrapperOptions.spanName(rpcMeta) : wrapperOptions.spanName;\n\n const wrappedFunction = (scope: Scope): unknown | Promise<unknown> => {\n // In certain situations, the passed context can become undefined.\n // For example, for Astro while prerendering pages at build time.\n // see: https://github.com/getsentry/sentry-javascript/issues/13217\n const context: typeof wrapperOptions.context | undefined = wrapperOptions.context;\n\n // see: https://github.com/getsentry/sentry-javascript/issues/22328\n // Resolved once per invocation and cached on its state: reading `ctx.waitUntil`\n // on a native context is a runtime getter call.\n const invocationState = getInvocationState();\n const waitUntil = invocationState\n ? getInvocationWaitUntil(invocationState)\n : context\n ? getOriginalWaitUntil(context as ExecutionContextCompat)?.bind(context)\n : undefined;\n const storage = resolveOriginalStorage(context, thisArg);\n\n let scopeClient = scope.getClient();\n // Re-init when the scope has no usable client (a previous handler disposed it, e.g.\n // DO alarm handlers) or for `startNewTrace`, so the client points at this\n // invocation's context. With `cacheClient: true` `init()` returns the isolate's\n // cached client and only creates (and caches) a fresh one when nothing is cached yet;\n // `cacheClient: false` creates one per invocation.\n if (startNewTrace || !scopeClient?.getTransport()) {\n const client = init({\n ...wrapperOptions.options,\n ctx: context as unknown as ExecutionContext | undefined,\n });\n scope.setClient(client);\n scopeClient = client;\n }\n\n const clientToDispose = scopeClient;\n const methodName = spanName || 'unknown';\n\n const teardown = async (): Promise<void> => {\n if (startNewTrace && storage) {\n storeSpanContext(storage, methodName);\n }\n await flushAndDispose(clientToDispose);\n };\n\n const onFulfilled = (res: unknown) => {\n waitUntil?.(teardown());\n return res;\n };\n\n const captureAndRethrow = (e: unknown): never => {\n captureException(e, {\n mechanism: {\n type: origin,\n handled: false,\n },\n });\n throw e;\n };\n\n const onRejected = (e: unknown) => {\n try {\n return captureAndRethrow(e);\n } finally {\n waitUntil?.(teardown());\n }\n };\n\n if (!spanName) {\n try {\n if (callback) {\n callback(...args);\n }\n\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(onFulfilled, onRejected);\n } else {\n return onFulfilled(result);\n }\n } catch (e) {\n return onRejected(e);\n }\n }\n\n const attributes = wrapperOptions.spanOp\n ? {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: origin,\n }\n : {};\n\n const executeSpan = (): unknown => {\n return startSpan({ name: methodName, attributes }, span => {\n if (startNewTrace && storage) {\n const storedContext = getStoredSpanContext(storage, methodName);\n\n if (storedContext) {\n span.addLinks(buildSpanLinks(storedContext));\n // TODO: Remove this once EAP can store span links. We currently only set this attribute so that we\n // can obtain the previous trace information from the EAP store. Long-term, EAP will handle\n // span links and then we should remove this again. Also throwing in a TODO(v11), to remind us\n // to check this at v11 time :)\n const sampledFlag = storedContext.sampled ? '1' : '0';\n span.setAttribute(\n 'sentry.previous_trace',\n `${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}`,\n );\n }\n }\n\n try {\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(undefined, captureAndRethrow);\n }\n return result;\n } catch (e) {\n return captureAndRethrow(e);\n }\n });\n };\n\n // The boundary flush (teardown) must run after the method span has ended, so the\n // span is in the buffer when that flush drains it. Running it inside the span\n // callback (before `startSpan` ends the span) would leave the span for the eager\n // path and cost a second flush per invocation.\n const runWithTeardown = (run: () => unknown): unknown => {\n let out: unknown;\n try {\n out = run();\n } catch (e) {\n // Synchronous throw: `startSpan` already ended the span and rethrew.\n waitUntil?.(teardown());\n throw e;\n }\n if (isThenable(out)) {\n return out.then(\n res => {\n waitUntil?.(teardown());\n return res;\n },\n e => {\n waitUntil?.(teardown());\n throw e;\n },\n );\n }\n waitUntil?.(teardown());\n return out;\n };\n\n if (rpcMeta) {\n return runWithTeardown(() =>\n continueTrace(\n { sentryTrace: rpcMeta['sentry-trace'] || '', baggage: rpcMeta.baggage || '' },\n executeSpan,\n ),\n );\n }\n\n if (startNewTrace) {\n return runWithTeardown(() => startNewTraceCore(() => executeSpan()));\n }\n\n return runWithTeardown(executeSpan);\n };\n\n return withInvocationIsolationScope(\n wrappedFunction,\n wrapperOptions.context as ExecutionContextCompat | undefined,\n );\n },\n }),\n noMark,\n );\n}\n"],"names":["isObjectLike","ensureInstrumented","rpcMeta","extractRpcMeta","getInvocationState","getInvocationWaitUntil","getOriginalWaitUntil","init","storeSpanContext","flushAndDispose","captureException","isThenable","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","getStoredSpanContext","buildSpanLinks","continueTrace","startNewTraceCore","withInvocationIsolationScope"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wrapMethodWithSentry.js","sources":["../../../src/wrapMethodWithSentry.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport type { SerializedTraceData } from '@sentry/core';\nimport { CODE_FUNCTION_NAME, SENTRY_OP, SENTRY_ORIGIN } from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport {\n isObjectLike,\n captureException,\n continueTrace,\n isThenable,\n type Scope,\n startNewTrace as startNewTraceCore,\n startSpan,\n} from '@sentry/core';\nimport type { CloudflareOptions } from './client';\nimport type { ExecutionContextCompat } from './executionContext';\nimport { flushAndDispose, getOriginalWaitUntil } from './flush';\nimport { ensureInstrumented } from './instrument';\nimport { init } from './sdk';\nimport { getInvocationState, getInvocationWaitUntil } from './utils/invocationContext';\nimport { withInvocationIsolationScope } from './utils/invocationScope';\nimport { extractRpcMeta } from './utils/rpcMeta';\nimport { buildSpanLinks, getStoredSpanContext, storeSpanContext } from './utils/traceLinks';\n\n/** Extended DurableObjectState with originalStorage exposed by instrumentContext */\nexport interface InstrumentedDurableObjectState extends DurableObjectState {\n originalStorage?: DurableObjectStorage;\n}\n\n/**\n * Resolves uninstrumented DO storage for the current invocation.\n * Prefer `thisArg.ctx` (the live Durable Object instance) over the context captured at\n * construction time to avoid cross-DO I/O errors in the same isolate.\n */\nfunction resolveOriginalStorage(\n context: ExecutionContext | InstrumentedDurableObjectState | undefined,\n thisArg: unknown,\n): DurableObjectStorage | undefined {\n if (isObjectLike(thisArg) && 'ctx' in thisArg) {\n const doCtx = (thisArg as { ctx: InstrumentedDurableObjectState }).ctx;\n if (doCtx?.originalStorage) {\n return doCtx.originalStorage;\n }\n }\n\n if (context && 'originalStorage' in context && context.originalStorage) {\n return context.originalStorage;\n }\n\n return undefined;\n}\n\ntype MethodWrapperOptions = {\n /**\n * The span name, or a resolver called with the RPC metadata of the current call.\n * Returning `undefined` skips the span and only captures errors.\n */\n spanName?: string | ((rpcMeta: SerializedTraceData | undefined) => string | undefined);\n spanOp?: string;\n options: CloudflareOptions;\n context: ExecutionContext | InstrumentedDurableObjectState;\n /**\n * If true, starts a fresh trace instead of inheriting from a parent trace.\n * Useful for scheduled/independent invocations like alarms.\n *\n * If true, it also stores the current span context and links to the previous invocation's span.\n * Uses Durable Object storage to persist the link. The link is set asynchronously via `span.addLinks()`\n * in a `waitUntil` to avoid blocking.\n *\n * @default false\n */\n startNewTrace?: boolean;\n /**\n * The trace origin identifying which instrumentation created the span, e.g. `auto.faas.cloudflare.durable_object`.\n * Used both as the span's `sentry.origin` attribute and as the `mechanism.type` for captured exceptions.\n */\n origin: string;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type UncheckedMethod = (...args: any[]) => any;\ntype OriginalMethod = UncheckedMethod;\n\n/**\n * Wraps a method with Sentry error tracking and optional tracing.\n * Supports starting new traces and linking to previous invocations via Durable Object storage.\n *\n * @param wrapperOptions - The options for the wrapper.\n * @param handler - The method to wrap.\n * @param callback - The callback to call.\n * @param noMark - Whether to mark the method as instrumented.\n * @returns The wrapped method.\n */\nexport function wrapMethodWithSentry<T extends OriginalMethod>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n noMark?: true,\n): T {\n return ensureInstrumented(\n handler,\n original =>\n new Proxy(original, {\n apply(target, thisArg, rawArgs: Parameters<T>) {\n const { startNewTrace, origin } = wrapperOptions;\n\n // For RPC methods, extract Sentry trace context from the trailing argument.\n // The caller side (instrumentDurableObjectStub / JSRPC proxy) appends it;\n // we strip it here so the user's method never sees it.\n let args = rawArgs;\n let rpcMeta: SerializedTraceData | undefined;\n\n if (wrapperOptions.spanOp === 'rpc') {\n const extracted = extractRpcMeta(rawArgs);\n args = extracted.args;\n rpcMeta = extracted.rpcMeta;\n }\n\n const spanName =\n typeof wrapperOptions.spanName === 'function' ? wrapperOptions.spanName(rpcMeta) : wrapperOptions.spanName;\n\n const wrappedFunction = (scope: Scope): unknown | Promise<unknown> => {\n // In certain situations, the passed context can become undefined.\n // For example, for Astro while prerendering pages at build time.\n // see: https://github.com/getsentry/sentry-javascript/issues/13217\n const context: typeof wrapperOptions.context | undefined = wrapperOptions.context;\n\n // see: https://github.com/getsentry/sentry-javascript/issues/22328\n // Resolved once per invocation and cached on its state: reading `ctx.waitUntil`\n // on a native context is a runtime getter call.\n const invocationState = getInvocationState();\n const waitUntil = invocationState\n ? getInvocationWaitUntil(invocationState)\n : context\n ? getOriginalWaitUntil(context as ExecutionContextCompat)?.bind(context)\n : undefined;\n const storage = resolveOriginalStorage(context, thisArg);\n\n let scopeClient = scope.getClient();\n // Re-init when the scope has no usable client (a previous handler disposed it, e.g.\n // DO alarm handlers) or for `startNewTrace`, so the client points at this\n // invocation's context. With `cacheClient: true` `init()` returns the isolate's\n // cached client and only creates (and caches) a fresh one when nothing is cached yet;\n // `cacheClient: false` creates one per invocation.\n if (startNewTrace || !scopeClient?.getTransport()) {\n const client = init({\n ...wrapperOptions.options,\n ctx: context as unknown as ExecutionContext | undefined,\n });\n scope.setClient(client);\n scopeClient = client;\n }\n\n const clientToDispose = scopeClient;\n const methodName = spanName || 'unknown';\n\n const teardown = async (): Promise<void> => {\n if (startNewTrace && storage) {\n storeSpanContext(storage, methodName);\n }\n await flushAndDispose(clientToDispose);\n };\n\n const onFulfilled = (res: unknown) => {\n waitUntil?.(teardown());\n return res;\n };\n\n const captureAndRethrow = (e: unknown): never => {\n captureException(e, {\n mechanism: {\n type: origin,\n handled: false,\n },\n });\n throw e;\n };\n\n const onRejected = (e: unknown) => {\n try {\n return captureAndRethrow(e);\n } finally {\n waitUntil?.(teardown());\n }\n };\n\n if (!spanName) {\n try {\n if (callback) {\n callback(...args);\n }\n\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(onFulfilled, onRejected);\n } else {\n return onFulfilled(result);\n }\n } catch (e) {\n return onRejected(e);\n }\n }\n\n const attributes = wrapperOptions.spanOp\n ? {\n [SENTRY_OP]: wrapperOptions.spanOp,\n [SENTRY_ORIGIN]: origin,\n // `function` spans are already named like their function name, so we just set `code.function.name` here.\n ...(wrapperOptions.spanOp === FUNCTION && { [CODE_FUNCTION_NAME]: methodName }),\n }\n : {};\n\n const executeSpan = (): unknown => {\n return startSpan({ name: methodName, attributes }, span => {\n if (startNewTrace && storage) {\n const storedContext = getStoredSpanContext(storage, methodName);\n\n if (storedContext) {\n span.addLinks(buildSpanLinks(storedContext));\n // TODO(v12): Remove this once the Sentry trace view finds linked traces via span links.\n // EAP stores span links, but the trace view still reads this attribute to navigate to the\n // previous/next trace.\n const sampledFlag = storedContext.sampled ? '1' : '0';\n span.setAttribute(\n 'sentry.previous_trace',\n `${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}`,\n );\n }\n }\n\n try {\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(undefined, captureAndRethrow);\n }\n return result;\n } catch (e) {\n return captureAndRethrow(e);\n }\n });\n };\n\n // The boundary flush (teardown) must run after the method span has ended, so the\n // span is in the buffer when that flush drains it. Running it inside the span\n // callback (before `startSpan` ends the span) would leave the span for the eager\n // path and cost a second flush per invocation.\n const runWithTeardown = (run: () => unknown): unknown => {\n let out: unknown;\n try {\n out = run();\n } catch (e) {\n // Synchronous throw: `startSpan` already ended the span and rethrew.\n waitUntil?.(teardown());\n throw e;\n }\n if (isThenable(out)) {\n return out.then(\n res => {\n waitUntil?.(teardown());\n return res;\n },\n e => {\n waitUntil?.(teardown());\n throw e;\n },\n );\n }\n waitUntil?.(teardown());\n return out;\n };\n\n if (rpcMeta) {\n return runWithTeardown(() =>\n continueTrace(\n { sentryTrace: rpcMeta['sentry-trace'] || '', baggage: rpcMeta.baggage || '' },\n executeSpan,\n ),\n );\n }\n\n if (startNewTrace) {\n return runWithTeardown(() => startNewTraceCore(() => executeSpan()));\n }\n\n return runWithTeardown(executeSpan);\n };\n\n return withInvocationIsolationScope(\n wrappedFunction,\n wrapperOptions.context as ExecutionContextCompat | undefined,\n );\n },\n }),\n noMark,\n );\n}\n"],"names":["isObjectLike","ensureInstrumented","rpcMeta","extractRpcMeta","getInvocationState","getInvocationWaitUntil","getOriginalWaitUntil","init","storeSpanContext","flushAndDispose","captureException","isThenable","attributes","SENTRY_OP","SENTRY_ORIGIN","FUNCTION","CODE_FUNCTION_NAME","startSpan","getStoredSpanContext","buildSpanLinks","continueTrace","startNewTraceCore","withInvocationIsolationScope"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ const attributes = require('@sentry/conventions/attributes');
|
|
|
4
4
|
const op = require('@sentry/conventions/op');
|
|
5
5
|
const core = require('@sentry/core');
|
|
6
6
|
const httpServer = require('./integrations/httpServer.js');
|
|
7
|
+
const orchestrionDeferredChannels = require('./orchestrion-deferred-channels.js');
|
|
7
8
|
const flush = require('./flush.js');
|
|
8
9
|
const scopeUtils = require('./scope-utils.js');
|
|
9
10
|
const invocationContext = require('./utils/invocationContext.js');
|
|
@@ -22,6 +23,7 @@ function wrapRequestHandlerWithInit(wrapperOptions, handler, initSdk) {
|
|
|
22
23
|
const errorMechanismType = getRequestErrorMechanismType(context);
|
|
23
24
|
const client = initSdk({ ...options, ctx: context });
|
|
24
25
|
isolationScope.setClient(client);
|
|
26
|
+
orchestrionDeferredChannels.flushDeferredChannelEvents();
|
|
25
27
|
const urlObject = core.parseStringToURLObject(request.url);
|
|
26
28
|
const [rawName, attributes$1] = core.getHttpSpanDetailsFromUrlObject(
|
|
27
29
|
urlObject,
|