@sentry/cloudflare 9.31.0 → 9.33.0

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.
Files changed (80) hide show
  1. package/build/cjs/client.js +18 -3
  2. package/build/cjs/client.js.map +1 -1
  3. package/build/cjs/durableobject.js +5 -3
  4. package/build/cjs/durableobject.js.map +1 -1
  5. package/build/cjs/flush.js +36 -0
  6. package/build/cjs/flush.js.map +1 -0
  7. package/build/cjs/handler.js +13 -8
  8. package/build/cjs/handler.js.map +1 -1
  9. package/build/cjs/index.js +4 -0
  10. package/build/cjs/index.js.map +1 -1
  11. package/build/cjs/integrations/tracing/vercelai.js +45 -0
  12. package/build/cjs/integrations/tracing/vercelai.js.map +1 -0
  13. package/build/cjs/opentelemetry/tracer.js +78 -0
  14. package/build/cjs/opentelemetry/tracer.js.map +1 -0
  15. package/build/cjs/pages-plugin.js +3 -1
  16. package/build/cjs/pages-plugin.js.map +1 -1
  17. package/build/cjs/request.js +5 -3
  18. package/build/cjs/request.js.map +1 -1
  19. package/build/cjs/sdk.js +20 -1
  20. package/build/cjs/sdk.js.map +1 -1
  21. package/build/cjs/workflows.js +161 -0
  22. package/build/cjs/workflows.js.map +1 -0
  23. package/build/esm/client.js +18 -3
  24. package/build/esm/client.js.map +1 -1
  25. package/build/esm/durableobject.js +5 -3
  26. package/build/esm/durableobject.js.map +1 -1
  27. package/build/esm/flush.js +34 -0
  28. package/build/esm/flush.js.map +1 -0
  29. package/build/esm/handler.js +13 -8
  30. package/build/esm/handler.js.map +1 -1
  31. package/build/esm/index.js +2 -0
  32. package/build/esm/index.js.map +1 -1
  33. package/build/esm/integrations/tracing/vercelai.js +43 -0
  34. package/build/esm/integrations/tracing/vercelai.js.map +1 -0
  35. package/build/esm/opentelemetry/tracer.js +76 -0
  36. package/build/esm/opentelemetry/tracer.js.map +1 -0
  37. package/build/esm/package.json +1 -1
  38. package/build/esm/pages-plugin.js +3 -1
  39. package/build/esm/pages-plugin.js.map +1 -1
  40. package/build/esm/request.js +5 -3
  41. package/build/esm/request.js.map +1 -1
  42. package/build/esm/sdk.js +20 -1
  43. package/build/esm/sdk.js.map +1 -1
  44. package/build/esm/workflows.js +159 -0
  45. package/build/esm/workflows.js.map +1 -0
  46. package/build/types/client.d.ts +32 -1
  47. package/build/types/client.d.ts.map +1 -1
  48. package/build/types/durableobject.d.ts.map +1 -1
  49. package/build/types/flush.d.ts +16 -0
  50. package/build/types/flush.d.ts.map +1 -0
  51. package/build/types/handler.d.ts.map +1 -1
  52. package/build/types/index.d.ts +2 -0
  53. package/build/types/index.d.ts.map +1 -1
  54. package/build/types/integrations/tracing/vercelai.d.ts +37 -0
  55. package/build/types/integrations/tracing/vercelai.d.ts.map +1 -0
  56. package/build/types/opentelemetry/tracer.d.ts +6 -0
  57. package/build/types/opentelemetry/tracer.d.ts.map +1 -0
  58. package/build/types/pages-plugin.d.ts.map +1 -1
  59. package/build/types/request.d.ts +1 -0
  60. package/build/types/request.d.ts.map +1 -1
  61. package/build/types/scope-utils.d.ts +1 -0
  62. package/build/types/scope-utils.d.ts.map +1 -1
  63. package/build/types/sdk.d.ts.map +1 -1
  64. package/build/types/utils/addOriginToSpan.d.ts +5 -0
  65. package/build/types/utils/addOriginToSpan.d.ts.map +1 -0
  66. package/build/types/utils/commonjs.d.ts +3 -0
  67. package/build/types/utils/commonjs.d.ts.map +1 -0
  68. package/build/types/workflows.d.ts +25 -0
  69. package/build/types/workflows.d.ts.map +1 -0
  70. package/build/types-ts3.8/client.d.ts +32 -1
  71. package/build/types-ts3.8/flush.d.ts +16 -0
  72. package/build/types-ts3.8/index.d.ts +2 -0
  73. package/build/types-ts3.8/integrations/tracing/vercelai.d.ts +37 -0
  74. package/build/types-ts3.8/opentelemetry/tracer.d.ts +6 -0
  75. package/build/types-ts3.8/request.d.ts +1 -0
  76. package/build/types-ts3.8/scope-utils.d.ts +1 -0
  77. package/build/types-ts3.8/utils/addOriginToSpan.d.ts +5 -0
  78. package/build/types-ts3.8/utils/commonjs.d.ts +3 -0
  79. package/build/types-ts3.8/workflows.d.ts +22 -0
  80. package/package.json +4 -3
package/build/cjs/sdk.js CHANGED
@@ -2,7 +2,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const core = require('@sentry/core');
4
4
  const client = require('./client.js');
5
+ const flush = require('./flush.js');
5
6
  const fetch = require('./integrations/fetch.js');
7
+ const tracer = require('./opentelemetry/tracer.js');
6
8
  const transport = require('./transport.js');
7
9
  const stacktrace = require('./vendor/stacktrace.js');
8
10
 
@@ -10,7 +12,9 @@ const stacktrace = require('./vendor/stacktrace.js');
10
12
  function getDefaultIntegrations(options) {
11
13
  const sendDefaultPii = options.sendDefaultPii ?? false;
12
14
  return [
13
- core.dedupeIntegration(),
15
+ // The Dedupe integration should not be used in workflows because we want to
16
+ // capture all step failures, even if they are the same error.
17
+ ...(options.enableDedupe === false ? [] : [core.dedupeIntegration()]),
14
18
  // TODO(v10): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`
15
19
  // eslint-disable-next-line deprecation/deprecation
16
20
  core.inboundFiltersIntegration(),
@@ -31,13 +35,28 @@ function init(options) {
31
35
  options.defaultIntegrations = getDefaultIntegrations(options);
32
36
  }
33
37
 
38
+ const flushLock = options.ctx ? flush.makeFlushLock(options.ctx) : undefined;
39
+ delete options.ctx;
40
+
34
41
  const clientOptions = {
35
42
  ...options,
36
43
  stackParser: core.stackParserFromStackParserOptions(options.stackParser || stacktrace.defaultStackParser),
37
44
  integrations: core.getIntegrationsToSetup(options),
38
45
  transport: options.transport || transport.makeCloudflareTransport,
46
+ flushLock,
39
47
  };
40
48
 
49
+ /**
50
+ * The Cloudflare SDK is not OpenTelemetry native, however, we set up some OpenTelemetry compatibility
51
+ * via a custom trace provider.
52
+ * This ensures that any spans emitted via `@opentelemetry/api` will be captured by Sentry.
53
+ * HOWEVER, big caveat: This does not handle custom context handling, it will always work off the current scope.
54
+ * This should be good enough for many, but not all integrations.
55
+ */
56
+ if (!options.skipOpenTelemetrySetup) {
57
+ tracer.setupOpenTelemetryTracer();
58
+ }
59
+
41
60
  return core.initAndBind(client.CloudflareClient, clientOptions) ;
42
61
  }
43
62
 
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sources":["../../src/sdk.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport {\n consoleIntegration,\n dedupeIntegration,\n functionToStringIntegration,\n getIntegrationsToSetup,\n inboundFiltersIntegration,\n initAndBind,\n linkedErrorsIntegration,\n requestDataIntegration,\n stackParserFromStackParserOptions,\n} from '@sentry/core';\nimport type { CloudflareClientOptions, CloudflareOptions } from './client';\nimport { CloudflareClient } from './client';\nimport { fetchIntegration } from './integrations/fetch';\nimport { makeCloudflareTransport } from './transport';\nimport { defaultStackParser } from './vendor/stacktrace';\n\n/** Get the default integrations for the Cloudflare SDK. */\nexport function getDefaultIntegrations(options: CloudflareOptions): Integration[] {\n const sendDefaultPii = options.sendDefaultPii ?? false;\n return [\n dedupeIntegration(),\n // TODO(v10): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`\n // eslint-disable-next-line deprecation/deprecation\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n linkedErrorsIntegration(),\n fetchIntegration(),\n // TODO(v10): the `include` object should be defined directly in the integration based on `sendDefaultPii`\n requestDataIntegration(sendDefaultPii ? undefined : { include: { cookies: false } }),\n consoleIntegration(),\n ];\n}\n\n/**\n * Initializes the cloudflare SDK.\n */\nexport function init(options: CloudflareOptions): CloudflareClient | undefined {\n if (options.defaultIntegrations === undefined) {\n options.defaultIntegrations = getDefaultIntegrations(options);\n }\n\n const clientOptions: CloudflareClientOptions = {\n ...options,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n integrations: getIntegrationsToSetup(options),\n transport: options.transport || makeCloudflareTransport,\n };\n\n return initAndBind(CloudflareClient, clientOptions) as CloudflareClient;\n}\n"],"names":["dedupeIntegration","inboundFiltersIntegration","functionToStringIntegration","linkedErrorsIntegration","fetchIntegration","requestDataIntegration","consoleIntegration","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","makeCloudflareTransport","initAndBind","CloudflareClient"],"mappings":";;;;;;;;AAkBA;AACO,SAAS,sBAAsB,CAAC,OAAO,EAAoC;AAClF,EAAE,MAAM,cAAe,GAAE,OAAO,CAAC,cAAA,IAAkB,KAAK;AACxD,EAAE,OAAO;AACT,IAAIA,sBAAiB,EAAE;AACvB;AACA;AACA,IAAIC,8BAAyB,EAAE;AAC/B,IAAIC,gCAA2B,EAAE;AACjC,IAAIC,4BAAuB,EAAE;AAC7B,IAAIC,sBAAgB,EAAE;AACtB;AACA,IAAIC,2BAAsB,CAAC,cAAe,GAAE,YAAY,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAM,EAAA,EAAG,CAAC;AACxF,IAAIC,uBAAkB,EAAE;AACxB,GAAG;AACH;;AAEA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAmD;AAC/E,EAAE,IAAI,OAAO,CAAC,mBAAoB,KAAI,SAAS,EAAE;AACjD,IAAI,OAAO,CAAC,mBAAA,GAAsB,sBAAsB,CAAC,OAAO,CAAC;AACjE;;AAEA,EAAE,MAAM,aAAa,GAA4B;AACjD,IAAI,GAAG,OAAO;AACd,IAAI,WAAW,EAAEC,sCAAiC,CAAC,OAAO,CAAC,WAAA,IAAeC,6BAAkB,CAAC;AAC7F,IAAI,YAAY,EAAEC,2BAAsB,CAAC,OAAO,CAAC;AACjD,IAAI,SAAS,EAAE,OAAO,CAAC,SAAA,IAAaC,iCAAuB;AAC3D,GAAG;;AAEH,EAAE,OAAOC,gBAAW,CAACC,uBAAgB,EAAE,aAAa,CAAE;AACtD;;;;;"}
1
+ {"version":3,"file":"sdk.js","sources":["../../src/sdk.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport {\n consoleIntegration,\n dedupeIntegration,\n functionToStringIntegration,\n getIntegrationsToSetup,\n inboundFiltersIntegration,\n initAndBind,\n linkedErrorsIntegration,\n requestDataIntegration,\n stackParserFromStackParserOptions,\n} from '@sentry/core';\nimport type { CloudflareClientOptions, CloudflareOptions } from './client';\nimport { CloudflareClient } from './client';\nimport { makeFlushLock } from './flush';\nimport { fetchIntegration } from './integrations/fetch';\nimport { setupOpenTelemetryTracer } from './opentelemetry/tracer';\nimport { makeCloudflareTransport } from './transport';\nimport { defaultStackParser } from './vendor/stacktrace';\n\n/** Get the default integrations for the Cloudflare SDK. */\nexport function getDefaultIntegrations(options: CloudflareOptions): Integration[] {\n const sendDefaultPii = options.sendDefaultPii ?? false;\n return [\n // The Dedupe integration should not be used in workflows because we want to\n // capture all step failures, even if they are the same error.\n ...(options.enableDedupe === false ? [] : [dedupeIntegration()]),\n // TODO(v10): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`\n // eslint-disable-next-line deprecation/deprecation\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n linkedErrorsIntegration(),\n fetchIntegration(),\n // TODO(v10): the `include` object should be defined directly in the integration based on `sendDefaultPii`\n requestDataIntegration(sendDefaultPii ? undefined : { include: { cookies: false } }),\n consoleIntegration(),\n ];\n}\n\n/**\n * Initializes the cloudflare SDK.\n */\nexport function init(options: CloudflareOptions): CloudflareClient | undefined {\n if (options.defaultIntegrations === undefined) {\n options.defaultIntegrations = getDefaultIntegrations(options);\n }\n\n const flushLock = options.ctx ? makeFlushLock(options.ctx) : undefined;\n delete options.ctx;\n\n const clientOptions: CloudflareClientOptions = {\n ...options,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n integrations: getIntegrationsToSetup(options),\n transport: options.transport || makeCloudflareTransport,\n flushLock,\n };\n\n /**\n * The Cloudflare SDK is not OpenTelemetry native, however, we set up some OpenTelemetry compatibility\n * via a custom trace provider.\n * This ensures that any spans emitted via `@opentelemetry/api` will be captured by Sentry.\n * HOWEVER, big caveat: This does not handle custom context handling, it will always work off the current scope.\n * This should be good enough for many, but not all integrations.\n */\n if (!options.skipOpenTelemetrySetup) {\n setupOpenTelemetryTracer();\n }\n\n return initAndBind(CloudflareClient, clientOptions) as CloudflareClient;\n}\n"],"names":["dedupeIntegration","inboundFiltersIntegration","functionToStringIntegration","linkedErrorsIntegration","fetchIntegration","requestDataIntegration","consoleIntegration","makeFlushLock","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","makeCloudflareTransport","setupOpenTelemetryTracer","initAndBind","CloudflareClient"],"mappings":";;;;;;;;;;AAoBA;AACO,SAAS,sBAAsB,CAAC,OAAO,EAAoC;AAClF,EAAE,MAAM,cAAe,GAAE,OAAO,CAAC,cAAA,IAAkB,KAAK;AACxD,EAAE,OAAO;AACT;AACA;AACA,IAAI,IAAI,OAAO,CAAC,YAAA,KAAiB,KAAM,GAAE,EAAC,GAAI,CAACA,sBAAiB,EAAE,CAAC,CAAC;AACpE;AACA;AACA,IAAIC,8BAAyB,EAAE;AAC/B,IAAIC,gCAA2B,EAAE;AACjC,IAAIC,4BAAuB,EAAE;AAC7B,IAAIC,sBAAgB,EAAE;AACtB;AACA,IAAIC,2BAAsB,CAAC,cAAe,GAAE,YAAY,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAM,EAAA,EAAG,CAAC;AACxF,IAAIC,uBAAkB,EAAE;AACxB,GAAG;AACH;;AAEA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAmD;AAC/E,EAAE,IAAI,OAAO,CAAC,mBAAoB,KAAI,SAAS,EAAE;AACjD,IAAI,OAAO,CAAC,mBAAA,GAAsB,sBAAsB,CAAC,OAAO,CAAC;AACjE;;AAEA,EAAE,MAAM,SAAA,GAAY,OAAO,CAAC,GAAI,GAAEC,mBAAa,CAAC,OAAO,CAAC,GAAG,CAAA,GAAI,SAAS;AACxE,EAAE,OAAO,OAAO,CAAC,GAAG;;AAEpB,EAAE,MAAM,aAAa,GAA4B;AACjD,IAAI,GAAG,OAAO;AACd,IAAI,WAAW,EAAEC,sCAAiC,CAAC,OAAO,CAAC,WAAA,IAAeC,6BAAkB,CAAC;AAC7F,IAAI,YAAY,EAAEC,2BAAsB,CAAC,OAAO,CAAC;AACjD,IAAI,SAAS,EAAE,OAAO,CAAC,SAAA,IAAaC,iCAAuB;AAC3D,IAAI,SAAS;AACb,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE;AACvC,IAAIC,+BAAwB,EAAE;AAC9B;;AAEA,EAAE,OAAOC,gBAAW,CAACC,uBAAgB,EAAE,aAAa,CAAE;AACtD;;;;;"}
@@ -0,0 +1,161 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const core = require('@sentry/core');
4
+ const async = require('./async.js');
5
+ const scopeUtils = require('./scope-utils.js');
6
+ const sdk = require('./sdk.js');
7
+
8
+ const UUID_REGEX = /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i;
9
+
10
+ function propagationContextFromInstanceId(instanceId) {
11
+ // Validate and normalize traceId - should be a valid UUID with or without hyphens
12
+ if (!UUID_REGEX.test(instanceId)) {
13
+ throw new Error("Invalid 'instanceId' for workflow: Sentry requires random UUIDs for instanceId.");
14
+ }
15
+
16
+ // Remove hyphens to get UUID without hyphens
17
+ const traceId = instanceId.replace(/-/g, '');
18
+
19
+ // Derive sampleRand from last 4 characters of the random UUID
20
+ //
21
+ // We cannot store any state between workflow steps, so we derive the
22
+ // sampleRand from the traceId itself. This ensures that the sampling is
23
+ // consistent across all steps in the same workflow instance.
24
+ const sampleRand = parseInt(traceId.slice(-4), 16) / 0xffff;
25
+
26
+ return {
27
+ traceId,
28
+ sampleRand,
29
+ };
30
+ }
31
+
32
+ async function workflowStepWithSentry(
33
+ instanceId,
34
+ options,
35
+ callback,
36
+ ) {
37
+ async.setAsyncLocalStorageAsyncContextStrategy();
38
+
39
+ return core.withIsolationScope(async isolationScope => {
40
+ const client = sdk.init({ ...options, enableDedupe: false });
41
+ isolationScope.setClient(client);
42
+
43
+ scopeUtils.addCloudResourceContext(isolationScope);
44
+
45
+ return core.withScope(async scope => {
46
+ const propagationContext = propagationContextFromInstanceId(instanceId);
47
+ scope.setPropagationContext(propagationContext);
48
+
49
+ // eslint-disable-next-line no-return-await
50
+ return await callback();
51
+ });
52
+ });
53
+ }
54
+
55
+ class WrappedWorkflowStep {
56
+ constructor(
57
+ _instanceId,
58
+ _ctx,
59
+ _options,
60
+ _step,
61
+ ) {this._instanceId = _instanceId;this._ctx = _ctx;this._options = _options;this._step = _step;}
62
+
63
+ async do(
64
+ name,
65
+ configOrCallback,
66
+ maybeCallback,
67
+ ) {
68
+ const userCallback = (maybeCallback || configOrCallback) ;
69
+ const config = typeof configOrCallback === 'function' ? undefined : configOrCallback;
70
+
71
+ const instrumentedCallback = async () => {
72
+ return workflowStepWithSentry(this._instanceId, this._options, async () => {
73
+ return core.startSpan(
74
+ {
75
+ op: 'function.step.do',
76
+ name,
77
+ attributes: {
78
+ 'cloudflare.workflow.timeout': config?.timeout,
79
+ 'cloudflare.workflow.retries.backoff': config?.retries?.backoff,
80
+ 'cloudflare.workflow.retries.delay': config?.retries?.delay,
81
+ 'cloudflare.workflow.retries.limit': config?.retries?.limit,
82
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.workflow',
83
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',
84
+ },
85
+ },
86
+ async span => {
87
+ try {
88
+ const result = await userCallback();
89
+ span.setStatus({ code: 1 });
90
+ return result;
91
+ } catch (error) {
92
+ core.captureException(error, { mechanism: { handled: true, type: 'cloudflare' } });
93
+ throw error;
94
+ } finally {
95
+ this._ctx.waitUntil(core.flush(2000));
96
+ }
97
+ },
98
+ );
99
+ });
100
+ };
101
+
102
+ return config ? this._step.do(name, config, instrumentedCallback) : this._step.do(name, instrumentedCallback);
103
+ }
104
+
105
+ async sleep(name, duration) {
106
+ return this._step.sleep(name, duration);
107
+ }
108
+
109
+ async sleepUntil(name, timestamp) {
110
+ return this._step.sleepUntil(name, timestamp);
111
+ }
112
+
113
+ async waitForEvent(
114
+ name,
115
+ options,
116
+ ) {
117
+ return this._step.waitForEvent(name, options);
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Instruments a Cloudflare Workflow class with Sentry.
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const InstrumentedWorkflow = instrumentWorkflowWithSentry(
127
+ * (env) => ({ dsn: env.SENTRY_DSN }),
128
+ * MyWorkflowClass
129
+ * );
130
+ *
131
+ * export default InstrumentedWorkflow;
132
+ * ```
133
+ *
134
+ * @param optionsCallback - Function that returns Sentry options to initialize Sentry
135
+ * @param WorkflowClass - The workflow class to instrument
136
+ * @returns Instrumented workflow class with the same interface
137
+ */
138
+ function instrumentWorkflowWithSentry
139
+
140
+ (optionsCallback, WorkFlowClass) {
141
+ return new Proxy(WorkFlowClass, {
142
+ construct(target, args, newTarget) {
143
+ const [ctx, env] = args;
144
+ const options = optionsCallback(env);
145
+ const instance = Reflect.construct(target, args, newTarget) ;
146
+ return new Proxy(instance, {
147
+ get(obj, prop, receiver) {
148
+ if (prop === 'run') {
149
+ return async function (event, step) {
150
+ return obj.run.call(obj, event, new WrappedWorkflowStep(event.instanceId, ctx, options, step));
151
+ };
152
+ }
153
+ return Reflect.get(obj, prop, receiver);
154
+ },
155
+ });
156
+ },
157
+ }) ;
158
+ }
159
+
160
+ exports.instrumentWorkflowWithSentry = instrumentWorkflowWithSentry;
161
+ //# sourceMappingURL=workflows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows.js","sources":["../../src/workflows.ts"],"sourcesContent":["import type { PropagationContext } from '@sentry/core';\nimport {\n captureException,\n flush,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n withIsolationScope,\n withScope,\n} from '@sentry/core';\nimport type {\n WorkflowEntrypoint,\n WorkflowEvent,\n WorkflowSleepDuration,\n WorkflowStep,\n WorkflowStepConfig,\n WorkflowStepEvent,\n WorkflowTimeoutDuration,\n} from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from './async';\nimport type { CloudflareOptions } from './client';\nimport { addCloudResourceContext } from './scope-utils';\nimport { init } from './sdk';\n\nconst UUID_REGEX = /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i;\n\nfunction propagationContextFromInstanceId(instanceId: string): PropagationContext {\n // Validate and normalize traceId - should be a valid UUID with or without hyphens\n if (!UUID_REGEX.test(instanceId)) {\n throw new Error(\"Invalid 'instanceId' for workflow: Sentry requires random UUIDs for instanceId.\");\n }\n\n // Remove hyphens to get UUID without hyphens\n const traceId = instanceId.replace(/-/g, '');\n\n // Derive sampleRand from last 4 characters of the random UUID\n //\n // We cannot store any state between workflow steps, so we derive the\n // sampleRand from the traceId itself. This ensures that the sampling is\n // consistent across all steps in the same workflow instance.\n const sampleRand = parseInt(traceId.slice(-4), 16) / 0xffff;\n\n return {\n traceId,\n sampleRand,\n };\n}\n\nasync function workflowStepWithSentry<V>(\n instanceId: string,\n options: CloudflareOptions,\n callback: () => V,\n): Promise<V> {\n setAsyncLocalStorageAsyncContextStrategy();\n\n return withIsolationScope(async isolationScope => {\n const client = init({ ...options, enableDedupe: false });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return withScope(async scope => {\n const propagationContext = propagationContextFromInstanceId(instanceId);\n scope.setPropagationContext(propagationContext);\n\n // eslint-disable-next-line no-return-await\n return await callback();\n });\n });\n}\n\nclass WrappedWorkflowStep implements WorkflowStep {\n public constructor(\n private _instanceId: string,\n private _ctx: ExecutionContext,\n private _options: CloudflareOptions,\n private _step: WorkflowStep,\n ) {}\n\n public async do<T extends Rpc.Serializable<T>>(name: string, callback: () => Promise<T>): Promise<T>;\n public async do<T extends Rpc.Serializable<T>>(\n name: string,\n config: WorkflowStepConfig,\n callback: () => Promise<T>,\n ): Promise<T>;\n public async do<T extends Rpc.Serializable<T>>(\n name: string,\n configOrCallback: WorkflowStepConfig | (() => Promise<T>),\n maybeCallback?: () => Promise<T>,\n ): Promise<T> {\n const userCallback = (maybeCallback || configOrCallback) as () => Promise<T>;\n const config = typeof configOrCallback === 'function' ? undefined : configOrCallback;\n\n const instrumentedCallback: () => Promise<T> = async () => {\n return workflowStepWithSentry(this._instanceId, this._options, async () => {\n return startSpan(\n {\n op: 'function.step.do',\n name,\n attributes: {\n 'cloudflare.workflow.timeout': config?.timeout,\n 'cloudflare.workflow.retries.backoff': config?.retries?.backoff,\n 'cloudflare.workflow.retries.delay': config?.retries?.delay,\n 'cloudflare.workflow.retries.limit': config?.retries?.limit,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.workflow',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async span => {\n try {\n const result = await userCallback();\n span.setStatus({ code: 1 });\n return result;\n } catch (error) {\n captureException(error, { mechanism: { handled: true, type: 'cloudflare' } });\n throw error;\n } finally {\n this._ctx.waitUntil(flush(2000));\n }\n },\n );\n });\n };\n\n return config ? this._step.do(name, config, instrumentedCallback) : this._step.do(name, instrumentedCallback);\n }\n\n public async sleep(name: string, duration: WorkflowSleepDuration): Promise<void> {\n return this._step.sleep(name, duration);\n }\n\n public async sleepUntil(name: string, timestamp: Date | number): Promise<void> {\n return this._step.sleepUntil(name, timestamp);\n }\n\n public async waitForEvent<T extends Rpc.Serializable<T>>(\n name: string,\n options: { type: string; timeout?: WorkflowTimeoutDuration | number },\n ): Promise<WorkflowStepEvent<T>> {\n return this._step.waitForEvent<T>(name, options);\n }\n}\n\n/**\n * Instruments a Cloudflare Workflow class with Sentry.\n *\n * @example\n * ```typescript\n * const InstrumentedWorkflow = instrumentWorkflowWithSentry(\n * (env) => ({ dsn: env.SENTRY_DSN }),\n * MyWorkflowClass\n * );\n *\n * export default InstrumentedWorkflow;\n * ```\n *\n * @param optionsCallback - Function that returns Sentry options to initialize Sentry\n * @param WorkflowClass - The workflow class to instrument\n * @returns Instrumented workflow class with the same interface\n */\nexport function instrumentWorkflowWithSentry<\n E, // Environment type\n P, // Payload type\n T extends WorkflowEntrypoint<E, P>, // WorkflowEntrypoint type\n C extends new (ctx: ExecutionContext, env: E) => T, // Constructor type of the WorkflowEntrypoint class\n>(optionsCallback: (env: E) => CloudflareOptions, WorkFlowClass: C): C {\n return new Proxy(WorkFlowClass, {\n construct(target: C, args: [ctx: ExecutionContext, env: E], newTarget) {\n const [ctx, env] = args;\n const options = optionsCallback(env);\n const instance = Reflect.construct(target, args, newTarget) as T;\n return new Proxy(instance, {\n get(obj, prop, receiver) {\n if (prop === 'run') {\n return async function (event: WorkflowEvent<P>, step: WorkflowStep): Promise<unknown> {\n return obj.run.call(obj, event, new WrappedWorkflowStep(event.instanceId, ctx, options, step));\n };\n }\n return Reflect.get(obj, prop, receiver);\n },\n });\n },\n }) as C;\n}\n"],"names":["setAsyncLocalStorageAsyncContextStrategy","withIsolationScope","init","addCloudResourceContext","withScope","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","captureException","flush"],"mappings":"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"}
@@ -7,6 +7,7 @@ import { ServerRuntimeClient, applySdkMetadata } from '@sentry/core';
7
7
  * @see ServerRuntimeClient for usage documentation.
8
8
  */
9
9
  class CloudflareClient extends ServerRuntimeClient {
10
+
10
11
  /**
11
12
  * Creates a new Cloudflare SDK instance.
12
13
  * @param options Configuration options for this SDK.
@@ -14,9 +15,10 @@ class CloudflareClient extends ServerRuntimeClient {
14
15
  constructor(options) {
15
16
  applySdkMetadata(options, 'cloudflare');
16
17
  options._metadata = options._metadata || {};
18
+ const { flushLock, ...serverOptions } = options;
17
19
 
18
20
  const clientOptions = {
19
- ...options,
21
+ ...serverOptions,
20
22
  platform: 'javascript',
21
23
  // TODO: Grab version information
22
24
  runtime: { name: 'cloudflare' },
@@ -24,10 +26,23 @@ class CloudflareClient extends ServerRuntimeClient {
24
26
  };
25
27
 
26
28
  super(clientOptions);
29
+ this._flushLock = flushLock;
27
30
  }
28
- }
29
31
 
30
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
32
+ /**
33
+ * Flushes pending operations and ensures all data is processed.
34
+ * If a timeout is provided, the operation will be completed within the specified time limit.
35
+ *
36
+ * @param {number} [timeout] - Optional timeout in milliseconds to force the completion of the flush operation.
37
+ * @return {Promise<boolean>} A promise that resolves to a boolean indicating whether the flush operation was successful.
38
+ */
39
+ async flush(timeout) {
40
+ if (this._flushLock) {
41
+ await this._flushLock.finalize();
42
+ }
43
+ return super.flush(timeout);
44
+ }
45
+ }
31
46
 
32
47
  export { CloudflareClient };
33
48
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sources":["../../src/client.ts"],"sourcesContent":["import type { ClientOptions, Options, ServerRuntimeClientOptions } from '@sentry/core';\nimport { applySdkMetadata, ServerRuntimeClient } from '@sentry/core';\nimport type { CloudflareTransportOptions } from './transport';\n\n/**\n * The Sentry Cloudflare SDK Client.\n *\n * @see CloudflareClientOptions for documentation on configuration options.\n * @see ServerRuntimeClient for usage documentation.\n */\nexport class CloudflareClient extends ServerRuntimeClient<CloudflareClientOptions> {\n /**\n * Creates a new Cloudflare SDK instance.\n * @param options Configuration options for this SDK.\n */\n public constructor(options: CloudflareClientOptions) {\n applySdkMetadata(options, 'cloudflare');\n options._metadata = options._metadata || {};\n\n const clientOptions: ServerRuntimeClientOptions = {\n ...options,\n platform: 'javascript',\n // TODO: Grab version information\n runtime: { name: 'cloudflare' },\n // TODO: Add server name\n };\n\n super(clientOptions);\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\ninterface BaseCloudflareOptions {}\n\n/**\n * Configuration options for the Sentry Cloudflare SDK\n *\n * @see @sentry/core Options for more information.\n */\nexport interface CloudflareOptions extends Options<CloudflareTransportOptions>, BaseCloudflareOptions {}\n\n/**\n * Configuration options for the Sentry Cloudflare SDK Client class\n *\n * @see CloudflareClient for more information.\n */\nexport interface CloudflareClientOptions extends ClientOptions<CloudflareTransportOptions>, BaseCloudflareOptions {}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,gBAAA,SAAyB,mBAAmB,CAA0B;AACnF;AACA;AACA;AACA;AACA,GAAS,WAAW,CAAC,OAAO,EAA2B;AACvD,IAAI,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC;AAC3C,IAAI,OAAO,CAAC,SAAU,GAAE,OAAO,CAAC,SAAA,IAAa,EAAE;;AAE/C,IAAI,MAAM,aAAa,GAA+B;AACtD,MAAM,GAAG,OAAO;AAChB,MAAM,QAAQ,EAAE,YAAY;AAC5B;AACA,MAAM,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc;AACrC;AACA,KAAK;;AAEL,IAAI,KAAK,CAAC,aAAa,CAAC;AACxB;AACA;;AAEA;;;;"}
1
+ {"version":3,"file":"client.js","sources":["../../src/client.ts"],"sourcesContent":["import type { ClientOptions, Options, ServerRuntimeClientOptions } from '@sentry/core';\nimport { applySdkMetadata, ServerRuntimeClient } from '@sentry/core';\nimport type { makeFlushLock } from './flush';\nimport type { CloudflareTransportOptions } from './transport';\n\n/**\n * The Sentry Cloudflare SDK Client.\n *\n * @see CloudflareClientOptions for documentation on configuration options.\n * @see ServerRuntimeClient for usage documentation.\n */\nexport class CloudflareClient extends ServerRuntimeClient {\n private readonly _flushLock: ReturnType<typeof makeFlushLock> | void;\n\n /**\n * Creates a new Cloudflare SDK instance.\n * @param options Configuration options for this SDK.\n */\n public constructor(options: CloudflareClientOptions) {\n applySdkMetadata(options, 'cloudflare');\n options._metadata = options._metadata || {};\n const { flushLock, ...serverOptions } = options;\n\n const clientOptions: ServerRuntimeClientOptions = {\n ...serverOptions,\n platform: 'javascript',\n // TODO: Grab version information\n runtime: { name: 'cloudflare' },\n // TODO: Add server name\n };\n\n super(clientOptions);\n this._flushLock = flushLock;\n }\n\n /**\n * Flushes pending operations and ensures all data is processed.\n * If a timeout is provided, the operation will be completed within the specified time limit.\n *\n * @param {number} [timeout] - Optional timeout in milliseconds to force the completion of the flush operation.\n * @return {Promise<boolean>} A promise that resolves to a boolean indicating whether the flush operation was successful.\n */\n public async flush(timeout?: number): Promise<boolean> {\n if (this._flushLock) {\n await this._flushLock.finalize();\n }\n return super.flush(timeout);\n }\n}\n\ninterface BaseCloudflareOptions {\n /**\n * @ignore Used internally to disable the deDupeIntegration for workflows.\n * @hidden Used internally to disable the deDupeIntegration for workflows.\n * @default true\n */\n enableDedupe?: boolean;\n\n /**\n * The Cloudflare SDK is not OpenTelemetry native, however, we set up some OpenTelemetry compatibility\n * via a custom trace provider.\n * This ensures that any spans emitted via `@opentelemetry/api` will be captured by Sentry.\n * HOWEVER, big caveat: This does not handle custom context handling, it will always work off the current scope.\n * This should be good enough for many, but not all integrations.\n *\n * If you want to opt-out of setting up the OpenTelemetry compatibility tracer, set this to `true`.\n *\n * @default false\n */\n skipOpenTelemetrySetup?: boolean;\n}\n\n/**\n * Configuration options for the Sentry Cloudflare SDK\n *\n * @see @sentry/core Options for more information.\n */\nexport interface CloudflareOptions extends Options<CloudflareTransportOptions>, BaseCloudflareOptions {\n ctx?: ExecutionContext;\n}\n\n/**\n * Configuration options for the Sentry Cloudflare SDK Client class\n *\n * @see CloudflareClient for more information.\n */\nexport interface CloudflareClientOptions extends ClientOptions<CloudflareTransportOptions>, BaseCloudflareOptions {\n flushLock?: ReturnType<typeof makeFlushLock>;\n}\n"],"names":[],"mappings":";;AAKA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,gBAAiB,SAAQ,mBAAoB,CAAA;;AAG1D;AACA;AACA;AACA;AACA,GAAS,WAAW,CAAC,OAAO,EAA2B;AACvD,IAAI,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC;AAC3C,IAAI,OAAO,CAAC,SAAU,GAAE,OAAO,CAAC,SAAA,IAAa,EAAE;AAC/C,IAAI,MAAM,EAAE,SAAS,EAAE,GAAG,aAAc,EAAA,GAAI,OAAO;;AAEnD,IAAI,MAAM,aAAa,GAA+B;AACtD,MAAM,GAAG,aAAa;AACtB,MAAM,QAAQ,EAAE,YAAY;AAC5B;AACA,MAAM,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc;AACrC;AACA,KAAK;;AAEL,IAAI,KAAK,CAAC,aAAa,CAAC;AACxB,IAAI,IAAI,CAAC,UAAW,GAAE,SAAS;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAS,MAAM,KAAK,CAAC,OAAO,EAA6B;AACzD,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;AACzB,MAAM,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE;AACtC;AACA,IAAI,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;AAC/B;AACA;;;;"}
@@ -30,9 +30,11 @@ function wrapMethodWithSentry(
30
30
  // see: https://github.com/getsentry/sentry-javascript/issues/13217
31
31
  const context = wrapperOptions.context ;
32
32
 
33
+ const waitUntil = context?.waitUntil?.bind?.(context);
34
+
33
35
  const currentClient = scope.getClient();
34
36
  if (!currentClient) {
35
- const client = init(wrapperOptions.options);
37
+ const client = init({ ...wrapperOptions.options, ctx: context });
36
38
  scope.setClient(client);
37
39
  }
38
40
 
@@ -51,7 +53,7 @@ function wrapMethodWithSentry(
51
53
  });
52
54
  throw e;
53
55
  } finally {
54
- context?.waitUntil(flush(2000));
56
+ waitUntil?.(flush(2000));
55
57
  }
56
58
  }
57
59
 
@@ -75,7 +77,7 @@ function wrapMethodWithSentry(
75
77
  });
76
78
  throw e;
77
79
  } finally {
78
- context?.waitUntil(flush(2000));
80
+ waitUntil?.(flush(2000));
79
81
  }
80
82
  });
81
83
  });
@@ -1 +1 @@
1
- {"version":3,"file":"durableobject.js","sources":["../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport {\n captureException,\n flush,\n getClient,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startSpan,\n withIsolationScope,\n withScope,\n} from '@sentry/core';\nimport type { DurableObject } from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from './async';\nimport type { CloudflareOptions } from './client';\nimport { isInstrumented, markAsInstrumented } from './instrument';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandler } from './request';\nimport { init } from './sdk';\n\ntype MethodWrapperOptions = {\n spanName?: string;\n spanOp?: string;\n options: CloudflareOptions;\n context: ExecutionContext | DurableObjectState;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction wrapMethodWithSentry<T extends (...args: any[]) => any>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n): T {\n if (isInstrumented(handler)) {\n return handler;\n }\n\n markAsInstrumented(handler);\n\n return new Proxy(handler, {\n apply(target, thisArg, args: Parameters<T>) {\n const currentClient = getClient();\n // if a client is already set, use withScope, otherwise use withIsolationScope\n const sentryWithScope = currentClient ? withScope : withIsolationScope;\n return sentryWithScope(async scope => {\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 = wrapperOptions.context as ExecutionContext | undefined;\n\n const currentClient = scope.getClient();\n if (!currentClient) {\n const client = init(wrapperOptions.options);\n scope.setClient(client);\n }\n\n if (!wrapperOptions.spanName) {\n try {\n if (callback) {\n callback(...args);\n }\n return await Reflect.apply(target, thisArg, args);\n } catch (e) {\n captureException(e, {\n mechanism: {\n type: 'cloudflare_durableobject',\n handled: false,\n },\n });\n throw e;\n } finally {\n context?.waitUntil(flush(2000));\n }\n }\n\n const attributes = wrapperOptions.spanOp\n ? {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare_durableobjects',\n }\n : {};\n\n // Only create these spans if they have a parent span.\n return startSpan({ name: wrapperOptions.spanName, attributes, onlyIfParent: true }, async () => {\n try {\n return await Reflect.apply(target, thisArg, args);\n } catch (e) {\n captureException(e, {\n mechanism: {\n type: 'cloudflare_durableobject',\n handled: false,\n },\n });\n throw e;\n } finally {\n context?.waitUntil(flush(2000));\n }\n });\n });\n },\n });\n}\n\n/**\n * Instruments a Durable Object class to capture errors and performance data.\n *\n * Instruments the following methods:\n * - fetch\n * - alarm\n * - webSocketMessage\n * - webSocketClose\n * - webSocketError\n *\n * as well as any other public RPC methods on the Durable Object instance.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param DurableObjectClass The Durable Object class to instrument.\n * @returns The instrumented Durable Object class.\n *\n * @example\n * ```ts\n * class MyDurableObjectBase extends DurableObject {\n * constructor(ctx: DurableObjectState, env: Env) {\n * super(ctx, env);\n * }\n * }\n *\n * export const MyDurableObject = instrumentDurableObjectWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyDurableObjectBase,\n * );\n * ```\n */\nexport function instrumentDurableObjectWithSentry<\n E,\n T extends DurableObject<E>,\n C extends new (state: DurableObjectState, env: E) => T,\n>(optionsCallback: (env: E) => CloudflareOptions, DurableObjectClass: C): C {\n return new Proxy(DurableObjectClass, {\n construct(target, [context, env]) {\n setAsyncLocalStorageAsyncContextStrategy();\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n const obj = new target(context, env);\n\n // These are the methods that are available on a Durable Object\n // ref: https://developers.cloudflare.com/durable-objects/api/base/\n // obj.alarm\n // obj.fetch\n // obj.webSocketError\n // obj.webSocketClose\n // obj.webSocketMessage\n\n // Any other public methods on the Durable Object instance are RPC calls.\n\n if (obj.fetch && typeof obj.fetch === 'function' && !isInstrumented(obj.fetch)) {\n obj.fetch = new Proxy(obj.fetch, {\n apply(target, thisArg, args) {\n return wrapRequestHandler({ options, request: args[0], context }, () =>\n Reflect.apply(target, thisArg, args),\n );\n },\n });\n\n markAsInstrumented(obj.fetch);\n }\n\n if (obj.alarm && typeof obj.alarm === 'function') {\n obj.alarm = wrapMethodWithSentry({ options, context, spanName: 'alarm' }, obj.alarm);\n }\n\n if (obj.webSocketMessage && typeof obj.webSocketMessage === 'function') {\n obj.webSocketMessage = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketMessage' },\n obj.webSocketMessage,\n );\n }\n\n if (obj.webSocketClose && typeof obj.webSocketClose === 'function') {\n obj.webSocketClose = wrapMethodWithSentry({ options, context, spanName: 'webSocketClose' }, obj.webSocketClose);\n }\n\n if (obj.webSocketError && typeof obj.webSocketError === 'function') {\n obj.webSocketError = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketError' },\n obj.webSocketError,\n (_, error) =>\n captureException(error, {\n mechanism: {\n type: 'cloudflare_durableobject_websocket',\n handled: false,\n },\n }),\n );\n }\n\n for (const method of Object.getOwnPropertyNames(obj)) {\n if (\n method === 'fetch' ||\n method === 'alarm' ||\n method === 'webSocketError' ||\n method === 'webSocketClose' ||\n method === 'webSocketMessage'\n ) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const value = (obj as any)[method] as unknown;\n if (typeof value === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n (obj as any)[method] = wrapMethodWithSentry(\n { options, context, spanName: method, spanOp: 'rpc' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value as (...args: any[]) => any,\n );\n }\n }\n\n return obj;\n },\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"durableobject.js","sources":["../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport {\n captureException,\n flush,\n getClient,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startSpan,\n withIsolationScope,\n withScope,\n} from '@sentry/core';\nimport type { DurableObject } from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from './async';\nimport type { CloudflareOptions } from './client';\nimport { isInstrumented, markAsInstrumented } from './instrument';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandler } from './request';\nimport { init } from './sdk';\n\ntype MethodWrapperOptions = {\n spanName?: string;\n spanOp?: string;\n options: CloudflareOptions;\n context: ExecutionContext | DurableObjectState;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction wrapMethodWithSentry<T extends (...args: any[]) => any>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n): T {\n if (isInstrumented(handler)) {\n return handler;\n }\n\n markAsInstrumented(handler);\n\n return new Proxy(handler, {\n apply(target, thisArg, args: Parameters<T>) {\n const currentClient = getClient();\n // if a client is already set, use withScope, otherwise use withIsolationScope\n const sentryWithScope = currentClient ? withScope : withIsolationScope;\n return sentryWithScope(async scope => {\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 = wrapperOptions.context as ExecutionContext | undefined;\n\n const waitUntil = context?.waitUntil?.bind?.(context);\n\n const currentClient = scope.getClient();\n if (!currentClient) {\n const client = init({ ...wrapperOptions.options, ctx: context });\n scope.setClient(client);\n }\n\n if (!wrapperOptions.spanName) {\n try {\n if (callback) {\n callback(...args);\n }\n return await Reflect.apply(target, thisArg, args);\n } catch (e) {\n captureException(e, {\n mechanism: {\n type: 'cloudflare_durableobject',\n handled: false,\n },\n });\n throw e;\n } finally {\n waitUntil?.(flush(2000));\n }\n }\n\n const attributes = wrapperOptions.spanOp\n ? {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare_durableobjects',\n }\n : {};\n\n // Only create these spans if they have a parent span.\n return startSpan({ name: wrapperOptions.spanName, attributes, onlyIfParent: true }, async () => {\n try {\n return await Reflect.apply(target, thisArg, args);\n } catch (e) {\n captureException(e, {\n mechanism: {\n type: 'cloudflare_durableobject',\n handled: false,\n },\n });\n throw e;\n } finally {\n waitUntil?.(flush(2000));\n }\n });\n });\n },\n });\n}\n\n/**\n * Instruments a Durable Object class to capture errors and performance data.\n *\n * Instruments the following methods:\n * - fetch\n * - alarm\n * - webSocketMessage\n * - webSocketClose\n * - webSocketError\n *\n * as well as any other public RPC methods on the Durable Object instance.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param DurableObjectClass The Durable Object class to instrument.\n * @returns The instrumented Durable Object class.\n *\n * @example\n * ```ts\n * class MyDurableObjectBase extends DurableObject {\n * constructor(ctx: DurableObjectState, env: Env) {\n * super(ctx, env);\n * }\n * }\n *\n * export const MyDurableObject = instrumentDurableObjectWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyDurableObjectBase,\n * );\n * ```\n */\nexport function instrumentDurableObjectWithSentry<\n E,\n T extends DurableObject<E>,\n C extends new (state: DurableObjectState, env: E) => T,\n>(optionsCallback: (env: E) => CloudflareOptions, DurableObjectClass: C): C {\n return new Proxy(DurableObjectClass, {\n construct(target, [context, env]) {\n setAsyncLocalStorageAsyncContextStrategy();\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n const obj = new target(context, env);\n\n // These are the methods that are available on a Durable Object\n // ref: https://developers.cloudflare.com/durable-objects/api/base/\n // obj.alarm\n // obj.fetch\n // obj.webSocketError\n // obj.webSocketClose\n // obj.webSocketMessage\n\n // Any other public methods on the Durable Object instance are RPC calls.\n\n if (obj.fetch && typeof obj.fetch === 'function' && !isInstrumented(obj.fetch)) {\n obj.fetch = new Proxy(obj.fetch, {\n apply(target, thisArg, args) {\n return wrapRequestHandler({ options, request: args[0], context }, () =>\n Reflect.apply(target, thisArg, args),\n );\n },\n });\n\n markAsInstrumented(obj.fetch);\n }\n\n if (obj.alarm && typeof obj.alarm === 'function') {\n obj.alarm = wrapMethodWithSentry({ options, context, spanName: 'alarm' }, obj.alarm);\n }\n\n if (obj.webSocketMessage && typeof obj.webSocketMessage === 'function') {\n obj.webSocketMessage = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketMessage' },\n obj.webSocketMessage,\n );\n }\n\n if (obj.webSocketClose && typeof obj.webSocketClose === 'function') {\n obj.webSocketClose = wrapMethodWithSentry({ options, context, spanName: 'webSocketClose' }, obj.webSocketClose);\n }\n\n if (obj.webSocketError && typeof obj.webSocketError === 'function') {\n obj.webSocketError = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketError' },\n obj.webSocketError,\n (_, error) =>\n captureException(error, {\n mechanism: {\n type: 'cloudflare_durableobject_websocket',\n handled: false,\n },\n }),\n );\n }\n\n for (const method of Object.getOwnPropertyNames(obj)) {\n if (\n method === 'fetch' ||\n method === 'alarm' ||\n method === 'webSocketError' ||\n method === 'webSocketClose' ||\n method === 'webSocketMessage'\n ) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const value = (obj as any)[method] as unknown;\n if (typeof value === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n (obj as any)[method] = wrapMethodWithSentry(\n { options, context, spanName: method, spanOp: 'rpc' },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value as (...args: any[]) => any,\n );\n }\n }\n\n return obj;\n },\n });\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Enhances the given execution context by wrapping its `waitUntil` method with a proxy
3
+ * to monitor pending tasks, and provides a flusher function to ensure all tasks
4
+ * have been completed before executing any subsequent logic.
5
+ *
6
+ * @param {ExecutionContext} context - The execution context to be enhanced. If no context is provided, the function returns undefined.
7
+ * @return {FlushLock} Returns a flusher function if a valid context is provided, otherwise undefined.
8
+ */
9
+ function makeFlushLock(context) {
10
+ let resolveAllDone = () => undefined;
11
+ const allDone = new Promise(res => {
12
+ resolveAllDone = res;
13
+ });
14
+ let pending = 0;
15
+ const originalWaitUntil = context.waitUntil.bind(context) ;
16
+ context.waitUntil = promise => {
17
+ pending++;
18
+ return originalWaitUntil(
19
+ promise.finally(() => {
20
+ if (--pending === 0) resolveAllDone();
21
+ }),
22
+ );
23
+ };
24
+ return Object.freeze({
25
+ ready: allDone,
26
+ finalize: () => {
27
+ if (pending === 0) resolveAllDone();
28
+ return allDone;
29
+ },
30
+ });
31
+ }
32
+
33
+ export { makeFlushLock };
34
+ //# sourceMappingURL=flush.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flush.js","sources":["../../src/flush.ts"],"sourcesContent":["import type { ExecutionContext } from '@cloudflare/workers-types';\n\ntype FlushLock = {\n readonly ready: Promise<void>;\n readonly finalize: () => Promise<void>;\n};\n\n/**\n * Enhances the given execution context by wrapping its `waitUntil` method with a proxy\n * to monitor pending tasks, and provides a flusher function to ensure all tasks\n * have been completed before executing any subsequent logic.\n *\n * @param {ExecutionContext} context - The execution context to be enhanced. If no context is provided, the function returns undefined.\n * @return {FlushLock} Returns a flusher function if a valid context is provided, otherwise undefined.\n */\nexport function makeFlushLock(context: ExecutionContext): FlushLock {\n let resolveAllDone: () => void = () => undefined;\n const allDone = new Promise<void>(res => {\n resolveAllDone = res;\n });\n let pending = 0;\n const originalWaitUntil = context.waitUntil.bind(context) as typeof context.waitUntil;\n context.waitUntil = promise => {\n pending++;\n return originalWaitUntil(\n promise.finally(() => {\n if (--pending === 0) resolveAllDone();\n }),\n );\n };\n return Object.freeze({\n ready: allDone,\n finalize: () => {\n if (pending === 0) resolveAllDone();\n return allDone;\n },\n });\n}\n"],"names":[],"mappings":"AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAC,OAAO,EAA+B;AACpE,EAAE,IAAI,cAAc,GAAe,MAAM,SAAS;AAClD,EAAE,MAAM,OAAQ,GAAE,IAAI,OAAO,CAAO,OAAO;AAC3C,IAAI,cAAA,GAAiB,GAAG;AACxB,GAAG,CAAC;AACJ,EAAE,IAAI,OAAQ,GAAE,CAAC;AACjB,EAAE,MAAM,iBAAkB,GAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAE;AAC5D,EAAE,OAAO,CAAC,SAAU,GAAE,WAAW;AACjC,IAAI,OAAO,EAAE;AACb,IAAI,OAAO,iBAAiB;AAC5B,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM;AAC5B,QAAQ,IAAI,EAAE,OAAA,KAAY,CAAC,EAAE,cAAc,EAAE;AAC7C,OAAO,CAAC;AACR,KAAK;AACL,GAAG;AACH,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,IAAI,KAAK,EAAE,OAAO;AAClB,IAAI,QAAQ,EAAE,MAAM;AACpB,MAAM,IAAI,OAAQ,KAAI,CAAC,EAAE,cAAc,EAAE;AACzC,MAAM,OAAO,OAAO;AACpB,KAAK;AACL,GAAG,CAAC;AACJ;;;;"}
@@ -65,8 +65,9 @@ function withSentry(
65
65
  const [event, env, context] = args;
66
66
  return withIsolationScope(isolationScope => {
67
67
  const options = getFinalOptions(optionsCallback(env), env);
68
+ const waitUntil = context.waitUntil.bind(context);
68
69
 
69
- const client = init(options);
70
+ const client = init({ ...options, ctx: context });
70
71
  isolationScope.setClient(client);
71
72
 
72
73
  addCloudResourceContext(isolationScope);
@@ -90,7 +91,7 @@ function withSentry(
90
91
  captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
91
92
  throw e;
92
93
  } finally {
93
- context.waitUntil(flush(2000));
94
+ waitUntil(flush(2000));
94
95
  }
95
96
  },
96
97
  );
@@ -107,8 +108,9 @@ function withSentry(
107
108
  const [emailMessage, env, context] = args;
108
109
  return withIsolationScope(isolationScope => {
109
110
  const options = getFinalOptions(optionsCallback(env), env);
111
+ const waitUntil = context.waitUntil.bind(context);
110
112
 
111
- const client = init(options);
113
+ const client = init({ ...options, ctx: context });
112
114
  isolationScope.setClient(client);
113
115
 
114
116
  addCloudResourceContext(isolationScope);
@@ -130,7 +132,7 @@ function withSentry(
130
132
  captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
131
133
  throw e;
132
134
  } finally {
133
- context.waitUntil(flush(2000));
135
+ waitUntil(flush(2000));
134
136
  }
135
137
  },
136
138
  );
@@ -148,8 +150,9 @@ function withSentry(
148
150
 
149
151
  return withIsolationScope(isolationScope => {
150
152
  const options = getFinalOptions(optionsCallback(env), env);
153
+ const waitUntil = context.waitUntil.bind(context);
151
154
 
152
- const client = init(options);
155
+ const client = init({ ...options, ctx: context });
153
156
  isolationScope.setClient(client);
154
157
 
155
158
  addCloudResourceContext(isolationScope);
@@ -176,7 +179,7 @@ function withSentry(
176
179
  captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
177
180
  throw e;
178
181
  } finally {
179
- context.waitUntil(flush(2000));
182
+ waitUntil(flush(2000));
180
183
  }
181
184
  },
182
185
  );
@@ -195,7 +198,9 @@ function withSentry(
195
198
  return withIsolationScope(async isolationScope => {
196
199
  const options = getFinalOptions(optionsCallback(env), env);
197
200
 
198
- const client = init(options);
201
+ const waitUntil = context.waitUntil.bind(context);
202
+
203
+ const client = init({ ...options, ctx: context });
199
204
  isolationScope.setClient(client);
200
205
 
201
206
  addCloudResourceContext(isolationScope);
@@ -206,7 +211,7 @@ function withSentry(
206
211
  captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
207
212
  throw e;
208
213
  } finally {
209
- context.waitUntil(flush(2000));
214
+ waitUntil(flush(2000));
210
215
  }
211
216
  });
212
217
  },
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sources":["../../src/handler.ts"],"sourcesContent":["import {\n captureException,\n flush,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n withIsolationScope,\n} from '@sentry/core';\nimport { setAsyncLocalStorageAsyncContextStrategy } from './async';\nimport type { CloudflareOptions } from './client';\nimport { isInstrumented, markAsInstrumented } from './instrument';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandler } from './request';\nimport { addCloudResourceContext } from './scope-utils';\nimport { init } from './sdk';\n\n/**\n * Wrapper for Cloudflare handlers.\n *\n * Initializes the SDK and wraps the handler with Sentry instrumentation.\n *\n * Automatically instruments the `fetch` method of the handler.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param handler {ExportedHandler} The handler to wrap.\n * @returns The wrapped handler.\n */\n// eslint-disable-next-line complexity\nexport function withSentry<Env = unknown, QueueHandlerMessage = unknown, CfHostMetadata = unknown>(\n optionsCallback: (env: Env) => CloudflareOptions,\n handler: ExportedHandler<Env, QueueHandlerMessage, CfHostMetadata>,\n): ExportedHandler<Env, QueueHandlerMessage, CfHostMetadata> {\n setAsyncLocalStorageAsyncContextStrategy();\n\n try {\n if ('fetch' in handler && typeof handler.fetch === 'function' && !isInstrumented(handler.fetch)) {\n handler.fetch = new Proxy(handler.fetch, {\n apply(target, thisArg, args: Parameters<ExportedHandlerFetchHandler<Env, CfHostMetadata>>) {\n const [request, env, context] = args;\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n return wrapRequestHandler({ options, request, context }, () => target.apply(thisArg, args));\n },\n });\n\n markAsInstrumented(handler.fetch);\n }\n\n /* hono does not reach the catch block of the fetch handler and captureException needs to be called in the hono errorHandler */\n if (\n 'onError' in handler &&\n 'errorHandler' in handler &&\n typeof handler.errorHandler === 'function' &&\n !isInstrumented(handler.errorHandler)\n ) {\n handler.errorHandler = new Proxy(handler.errorHandler, {\n apply(target, thisArg, args) {\n const [err] = args;\n\n captureException(err, { mechanism: { handled: false, type: 'cloudflare' } });\n\n return Reflect.apply(target, thisArg, args);\n },\n });\n\n markAsInstrumented(handler.errorHandler);\n }\n\n if ('scheduled' in handler && typeof handler.scheduled === 'function' && !isInstrumented(handler.scheduled)) {\n handler.scheduled = new Proxy(handler.scheduled, {\n apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<Env>>) {\n const [event, env, context] = args;\n return withIsolationScope(isolationScope => {\n const options = getFinalOptions(optionsCallback(env), env);\n\n const client = init(options);\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.cron',\n name: `Scheduled Cron ${event.cron}`,\n attributes: {\n 'faas.cron': event.cron,\n 'faas.time': new Date(event.scheduledTime).toISOString(),\n 'faas.trigger': 'timer',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await (target.apply(thisArg, args) as ReturnType<typeof target>);\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });\n throw e;\n } finally {\n context.waitUntil(flush(2000));\n }\n },\n );\n });\n },\n });\n\n markAsInstrumented(handler.scheduled);\n }\n\n if ('email' in handler && typeof handler.email === 'function' && !isInstrumented(handler.email)) {\n handler.email = new Proxy(handler.email, {\n apply(target, thisArg, args: Parameters<EmailExportedHandler<Env>>) {\n const [emailMessage, env, context] = args;\n return withIsolationScope(isolationScope => {\n const options = getFinalOptions(optionsCallback(env), env);\n\n const client = init(options);\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.email',\n name: `Handle Email ${emailMessage.to}`,\n attributes: {\n 'faas.trigger': 'email',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.email',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await (target.apply(thisArg, args) as ReturnType<typeof target>);\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });\n throw e;\n } finally {\n context.waitUntil(flush(2000));\n }\n },\n );\n });\n },\n });\n\n markAsInstrumented(handler.email);\n }\n\n if ('queue' in handler && typeof handler.queue === 'function' && !isInstrumented(handler.queue)) {\n handler.queue = new Proxy(handler.queue, {\n apply(target, thisArg, args: Parameters<ExportedHandlerQueueHandler<Env, QueueHandlerMessage>>) {\n const [batch, env, context] = args;\n\n return withIsolationScope(isolationScope => {\n const options = getFinalOptions(optionsCallback(env), env);\n\n const client = init(options);\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.queue',\n name: `process ${batch.queue}`,\n attributes: {\n 'faas.trigger': 'pubsub',\n 'messaging.destination.name': batch.queue,\n 'messaging.system': 'cloudflare',\n 'messaging.batch.message_count': batch.messages.length,\n 'messaging.message.retry.count': batch.messages.reduce((acc, message) => acc + message.attempts, 0),\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'queue.process',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.queue',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await (target.apply(thisArg, args) as ReturnType<typeof target>);\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });\n throw e;\n } finally {\n context.waitUntil(flush(2000));\n }\n },\n );\n });\n },\n });\n\n markAsInstrumented(handler.queue);\n }\n\n if ('tail' in handler && typeof handler.tail === 'function' && !isInstrumented(handler.tail)) {\n handler.tail = new Proxy(handler.tail, {\n apply(target, thisArg, args: Parameters<ExportedHandlerTailHandler<Env>>) {\n const [, env, context] = args;\n\n return withIsolationScope(async isolationScope => {\n const options = getFinalOptions(optionsCallback(env), env);\n\n const client = init(options);\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n try {\n return await (target.apply(thisArg, args) as ReturnType<typeof target>);\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });\n throw e;\n } finally {\n context.waitUntil(flush(2000));\n }\n });\n },\n });\n\n markAsInstrumented(handler.tail);\n }\n\n // This is here because Miniflare sometimes cannot get instrumented\n } catch (e) {\n // Do not console anything here, we don't want to spam the console with errors\n }\n\n return handler;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","sources":["../../src/handler.ts"],"sourcesContent":["import {\n captureException,\n flush,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n withIsolationScope,\n} from '@sentry/core';\nimport { setAsyncLocalStorageAsyncContextStrategy } from './async';\nimport type { CloudflareOptions } from './client';\nimport { isInstrumented, markAsInstrumented } from './instrument';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandler } from './request';\nimport { addCloudResourceContext } from './scope-utils';\nimport { init } from './sdk';\n\n/**\n * Wrapper for Cloudflare handlers.\n *\n * Initializes the SDK and wraps the handler with Sentry instrumentation.\n *\n * Automatically instruments the `fetch` method of the handler.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param handler {ExportedHandler} The handler to wrap.\n * @returns The wrapped handler.\n */\n// eslint-disable-next-line complexity\nexport function withSentry<Env = unknown, QueueHandlerMessage = unknown, CfHostMetadata = unknown>(\n optionsCallback: (env: Env) => CloudflareOptions,\n handler: ExportedHandler<Env, QueueHandlerMessage, CfHostMetadata>,\n): ExportedHandler<Env, QueueHandlerMessage, CfHostMetadata> {\n setAsyncLocalStorageAsyncContextStrategy();\n\n try {\n if ('fetch' in handler && typeof handler.fetch === 'function' && !isInstrumented(handler.fetch)) {\n handler.fetch = new Proxy(handler.fetch, {\n apply(target, thisArg, args: Parameters<ExportedHandlerFetchHandler<Env, CfHostMetadata>>) {\n const [request, env, context] = args;\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n return wrapRequestHandler({ options, request, context }, () => target.apply(thisArg, args));\n },\n });\n\n markAsInstrumented(handler.fetch);\n }\n\n /* hono does not reach the catch block of the fetch handler and captureException needs to be called in the hono errorHandler */\n if (\n 'onError' in handler &&\n 'errorHandler' in handler &&\n typeof handler.errorHandler === 'function' &&\n !isInstrumented(handler.errorHandler)\n ) {\n handler.errorHandler = new Proxy(handler.errorHandler, {\n apply(target, thisArg, args) {\n const [err] = args;\n\n captureException(err, { mechanism: { handled: false, type: 'cloudflare' } });\n\n return Reflect.apply(target, thisArg, args);\n },\n });\n\n markAsInstrumented(handler.errorHandler);\n }\n\n if ('scheduled' in handler && typeof handler.scheduled === 'function' && !isInstrumented(handler.scheduled)) {\n handler.scheduled = new Proxy(handler.scheduled, {\n apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<Env>>) {\n const [event, env, context] = args;\n return withIsolationScope(isolationScope => {\n const options = getFinalOptions(optionsCallback(env), env);\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.cron',\n name: `Scheduled Cron ${event.cron}`,\n attributes: {\n 'faas.cron': event.cron,\n 'faas.time': new Date(event.scheduledTime).toISOString(),\n 'faas.trigger': 'timer',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await (target.apply(thisArg, args) as ReturnType<typeof target>);\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });\n throw e;\n } finally {\n waitUntil(flush(2000));\n }\n },\n );\n });\n },\n });\n\n markAsInstrumented(handler.scheduled);\n }\n\n if ('email' in handler && typeof handler.email === 'function' && !isInstrumented(handler.email)) {\n handler.email = new Proxy(handler.email, {\n apply(target, thisArg, args: Parameters<EmailExportedHandler<Env>>) {\n const [emailMessage, env, context] = args;\n return withIsolationScope(isolationScope => {\n const options = getFinalOptions(optionsCallback(env), env);\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.email',\n name: `Handle Email ${emailMessage.to}`,\n attributes: {\n 'faas.trigger': 'email',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.email',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await (target.apply(thisArg, args) as ReturnType<typeof target>);\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });\n throw e;\n } finally {\n waitUntil(flush(2000));\n }\n },\n );\n });\n },\n });\n\n markAsInstrumented(handler.email);\n }\n\n if ('queue' in handler && typeof handler.queue === 'function' && !isInstrumented(handler.queue)) {\n handler.queue = new Proxy(handler.queue, {\n apply(target, thisArg, args: Parameters<ExportedHandlerQueueHandler<Env, QueueHandlerMessage>>) {\n const [batch, env, context] = args;\n\n return withIsolationScope(isolationScope => {\n const options = getFinalOptions(optionsCallback(env), env);\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.queue',\n name: `process ${batch.queue}`,\n attributes: {\n 'faas.trigger': 'pubsub',\n 'messaging.destination.name': batch.queue,\n 'messaging.system': 'cloudflare',\n 'messaging.batch.message_count': batch.messages.length,\n 'messaging.message.retry.count': batch.messages.reduce((acc, message) => acc + message.attempts, 0),\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'queue.process',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.queue',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await (target.apply(thisArg, args) as ReturnType<typeof target>);\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });\n throw e;\n } finally {\n waitUntil(flush(2000));\n }\n },\n );\n });\n },\n });\n\n markAsInstrumented(handler.queue);\n }\n\n if ('tail' in handler && typeof handler.tail === 'function' && !isInstrumented(handler.tail)) {\n handler.tail = new Proxy(handler.tail, {\n apply(target, thisArg, args: Parameters<ExportedHandlerTailHandler<Env>>) {\n const [, env, context] = args;\n\n return withIsolationScope(async isolationScope => {\n const options = getFinalOptions(optionsCallback(env), env);\n\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n try {\n return await (target.apply(thisArg, args) as ReturnType<typeof target>);\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });\n throw e;\n } finally {\n waitUntil(flush(2000));\n }\n });\n },\n });\n\n markAsInstrumented(handler.tail);\n }\n\n // This is here because Miniflare sometimes cannot get instrumented\n } catch (e) {\n // Do not console anything here, we don't want to spam the console with errors\n }\n\n return handler;\n}\n"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@ export { wrapRequestHandler } from './request.js';
8
8
  export { CloudflareClient } from './client.js';
9
9
  export { getDefaultIntegrations } from './sdk.js';
10
10
  export { fetchIntegration } from './integrations/fetch.js';
11
+ export { vercelAIIntegration } from './integrations/tracing/vercelai.js';
11
12
  export { instrumentD1WithSentry } from './d1.js';
13
+ export { instrumentWorkflowWithSentry } from './workflows.js';
12
14
  export { setAsyncLocalStorageAsyncContextStrategy } from './async.js';
13
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}