@sentry/cloudflare 10.39.0 → 10.40.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.
- package/build/cjs/durableobject.js +9 -133
- package/build/cjs/durableobject.js.map +1 -1
- package/build/cjs/handler.js +6 -6
- package/build/cjs/handler.js.map +1 -1
- package/build/cjs/instrumentations/instrumentDurableObjectStorage.js +52 -0
- package/build/cjs/instrumentations/instrumentDurableObjectStorage.js.map +1 -0
- package/build/cjs/utils/instrumentContext.js +103 -0
- package/build/cjs/utils/instrumentContext.js.map +1 -0
- package/build/cjs/workflows.js +2 -2
- package/build/cjs/workflows.js.map +1 -1
- package/build/cjs/wrapMethodWithSentry.js +143 -0
- package/build/cjs/wrapMethodWithSentry.js.map +1 -0
- package/build/esm/durableobject.js +4 -128
- package/build/esm/durableobject.js.map +1 -1
- package/build/esm/handler.js +6 -6
- package/build/esm/handler.js.map +1 -1
- package/build/esm/instrumentations/instrumentDurableObjectStorage.js +50 -0
- package/build/esm/instrumentations/instrumentDurableObjectStorage.js.map +1 -0
- package/build/esm/package.json +1 -1
- package/build/esm/utils/instrumentContext.js +101 -0
- package/build/esm/utils/instrumentContext.js.map +1 -0
- package/build/esm/workflows.js +2 -2
- package/build/esm/workflows.js.map +1 -1
- package/build/esm/wrapMethodWithSentry.js +141 -0
- package/build/esm/wrapMethodWithSentry.js.map +1 -0
- package/build/types/durableobject.d.ts.map +1 -1
- package/build/types/instrumentations/instrumentDurableObjectStorage.d.ts +12 -0
- package/build/types/instrumentations/instrumentDurableObjectStorage.d.ts.map +1 -0
- package/build/types/utils/instrumentContext.d.ts +16 -0
- package/build/types/utils/instrumentContext.d.ts.map +1 -0
- package/build/types/wrapMethodWithSentry.d.ts +21 -0
- package/build/types/wrapMethodWithSentry.d.ts.map +1 -0
- package/build/types-ts3.8/instrumentations/instrumentDurableObjectStorage.d.ts +12 -0
- package/build/types-ts3.8/utils/instrumentContext.d.ts +16 -0
- package/build/types-ts3.8/wrapMethodWithSentry.d.ts +21 -0
- package/package.json +3 -4
- package/build/cjs/utils/copyExecutionContext.js +0 -69
- package/build/cjs/utils/copyExecutionContext.js.map +0 -1
- package/build/esm/utils/copyExecutionContext.js +0 -67
- package/build/esm/utils/copyExecutionContext.js.map +0 -1
- package/build/types/utils/copyExecutionContext.d.ts +0 -11
- package/build/types/utils/copyExecutionContext.d.ts.map +0 -1
- package/build/types-ts3.8/utils/copyExecutionContext.d.ts +0 -11
|
@@ -5,135 +5,11 @@ const async = require('./async.js');
|
|
|
5
5
|
const instrument = require('./instrument.js');
|
|
6
6
|
const options = require('./options.js');
|
|
7
7
|
const request = require('./request.js');
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const instrumentContext = require('./utils/instrumentContext.js');
|
|
9
|
+
const wrapMethodWithSentry = require('./wrapMethodWithSentry.js');
|
|
10
10
|
|
|
11
11
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
12
12
|
|
|
13
|
-
function wrapMethodWithSentry(
|
|
14
|
-
wrapperOptions,
|
|
15
|
-
handler,
|
|
16
|
-
callback,
|
|
17
|
-
noMark,
|
|
18
|
-
) {
|
|
19
|
-
if (instrument.isInstrumented(handler)) {
|
|
20
|
-
return handler;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (!noMark) {
|
|
24
|
-
instrument.markAsInstrumented(handler);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return new Proxy(handler, {
|
|
28
|
-
apply(target, thisArg, args) {
|
|
29
|
-
const currentClient = core.getClient();
|
|
30
|
-
// if a client is already set, use withScope, otherwise use withIsolationScope
|
|
31
|
-
const sentryWithScope = currentClient ? core.withScope : core.withIsolationScope;
|
|
32
|
-
|
|
33
|
-
const wrappedFunction = (scope) => {
|
|
34
|
-
// In certain situations, the passed context can become undefined.
|
|
35
|
-
// For example, for Astro while prerendering pages at build time.
|
|
36
|
-
// see: https://github.com/getsentry/sentry-javascript/issues/13217
|
|
37
|
-
const context = wrapperOptions.context ;
|
|
38
|
-
|
|
39
|
-
const waitUntil = context?.waitUntil?.bind?.(context);
|
|
40
|
-
|
|
41
|
-
const currentClient = scope.getClient();
|
|
42
|
-
if (!currentClient) {
|
|
43
|
-
const client = sdk.init({ ...wrapperOptions.options, ctx: context });
|
|
44
|
-
scope.setClient(client);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (!wrapperOptions.spanName) {
|
|
48
|
-
try {
|
|
49
|
-
if (callback) {
|
|
50
|
-
callback(...args);
|
|
51
|
-
}
|
|
52
|
-
const result = Reflect.apply(target, thisArg, args);
|
|
53
|
-
|
|
54
|
-
if (core.isThenable(result)) {
|
|
55
|
-
return result.then(
|
|
56
|
-
(res) => {
|
|
57
|
-
waitUntil?.(core.flush(2000));
|
|
58
|
-
return res;
|
|
59
|
-
},
|
|
60
|
-
(e) => {
|
|
61
|
-
core.captureException(e, {
|
|
62
|
-
mechanism: {
|
|
63
|
-
type: 'auto.faas.cloudflare.durable_object',
|
|
64
|
-
handled: false,
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
waitUntil?.(core.flush(2000));
|
|
68
|
-
throw e;
|
|
69
|
-
},
|
|
70
|
-
);
|
|
71
|
-
} else {
|
|
72
|
-
waitUntil?.(core.flush(2000));
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
} catch (e) {
|
|
76
|
-
core.captureException(e, {
|
|
77
|
-
mechanism: {
|
|
78
|
-
type: 'auto.faas.cloudflare.durable_object',
|
|
79
|
-
handled: false,
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
waitUntil?.(core.flush(2000));
|
|
83
|
-
throw e;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const attributes = wrapperOptions.spanOp
|
|
88
|
-
? {
|
|
89
|
-
[core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,
|
|
90
|
-
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.durable_object',
|
|
91
|
-
}
|
|
92
|
-
: {};
|
|
93
|
-
|
|
94
|
-
return core.startSpan({ name: wrapperOptions.spanName, attributes }, () => {
|
|
95
|
-
try {
|
|
96
|
-
const result = Reflect.apply(target, thisArg, args);
|
|
97
|
-
|
|
98
|
-
if (core.isThenable(result)) {
|
|
99
|
-
return result.then(
|
|
100
|
-
(res) => {
|
|
101
|
-
waitUntil?.(core.flush(2000));
|
|
102
|
-
return res;
|
|
103
|
-
},
|
|
104
|
-
(e) => {
|
|
105
|
-
core.captureException(e, {
|
|
106
|
-
mechanism: {
|
|
107
|
-
type: 'auto.faas.cloudflare.durable_object',
|
|
108
|
-
handled: false,
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
waitUntil?.(core.flush(2000));
|
|
112
|
-
throw e;
|
|
113
|
-
},
|
|
114
|
-
);
|
|
115
|
-
} else {
|
|
116
|
-
waitUntil?.(core.flush(2000));
|
|
117
|
-
return result;
|
|
118
|
-
}
|
|
119
|
-
} catch (e) {
|
|
120
|
-
core.captureException(e, {
|
|
121
|
-
mechanism: {
|
|
122
|
-
type: 'auto.faas.cloudflare.durable_object',
|
|
123
|
-
handled: false,
|
|
124
|
-
},
|
|
125
|
-
});
|
|
126
|
-
waitUntil?.(core.flush(2000));
|
|
127
|
-
throw e;
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
return sentryWithScope(wrappedFunction);
|
|
133
|
-
},
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
13
|
/**
|
|
138
14
|
* Instruments a Durable Object class to capture errors and performance data.
|
|
139
15
|
*
|
|
@@ -173,7 +49,7 @@ function instrumentDurableObjectWithSentry
|
|
|
173
49
|
return new Proxy(DurableObjectClass, {
|
|
174
50
|
construct(target, [ctx, env]) {
|
|
175
51
|
async.setAsyncLocalStorageAsyncContextStrategy();
|
|
176
|
-
const context =
|
|
52
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
177
53
|
|
|
178
54
|
const options$1 = options.getFinalOptions(optionsCallback(env), env);
|
|
179
55
|
|
|
@@ -202,22 +78,22 @@ function instrumentDurableObjectWithSentry
|
|
|
202
78
|
}
|
|
203
79
|
|
|
204
80
|
if (obj.alarm && typeof obj.alarm === 'function') {
|
|
205
|
-
obj.alarm = wrapMethodWithSentry({ options: options$1, context, spanName: 'alarm' }, obj.alarm);
|
|
81
|
+
obj.alarm = wrapMethodWithSentry.wrapMethodWithSentry({ options: options$1, context, spanName: 'alarm' }, obj.alarm);
|
|
206
82
|
}
|
|
207
83
|
|
|
208
84
|
if (obj.webSocketMessage && typeof obj.webSocketMessage === 'function') {
|
|
209
|
-
obj.webSocketMessage = wrapMethodWithSentry(
|
|
85
|
+
obj.webSocketMessage = wrapMethodWithSentry.wrapMethodWithSentry(
|
|
210
86
|
{ options: options$1, context, spanName: 'webSocketMessage' },
|
|
211
87
|
obj.webSocketMessage,
|
|
212
88
|
);
|
|
213
89
|
}
|
|
214
90
|
|
|
215
91
|
if (obj.webSocketClose && typeof obj.webSocketClose === 'function') {
|
|
216
|
-
obj.webSocketClose = wrapMethodWithSentry({ options: options$1, context, spanName: 'webSocketClose' }, obj.webSocketClose);
|
|
92
|
+
obj.webSocketClose = wrapMethodWithSentry.wrapMethodWithSentry({ options: options$1, context, spanName: 'webSocketClose' }, obj.webSocketClose);
|
|
217
93
|
}
|
|
218
94
|
|
|
219
95
|
if (obj.webSocketError && typeof obj.webSocketError === 'function') {
|
|
220
|
-
obj.webSocketError = wrapMethodWithSentry(
|
|
96
|
+
obj.webSocketError = wrapMethodWithSentry.wrapMethodWithSentry(
|
|
221
97
|
{ options: options$1, context, spanName: 'webSocketError' },
|
|
222
98
|
obj.webSocketError,
|
|
223
99
|
(_, error) =>
|
|
@@ -245,7 +121,7 @@ function instrumentDurableObjectWithSentry
|
|
|
245
121
|
const value = (obj )[method] ;
|
|
246
122
|
if (typeof value === 'function') {
|
|
247
123
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
248
|
-
(obj )[method] = wrapMethodWithSentry(
|
|
124
|
+
(obj )[method] = wrapMethodWithSentry.wrapMethodWithSentry(
|
|
249
125
|
{ options: options$1, context, spanName: method, spanOp: 'rpc' },
|
|
250
126
|
value ,
|
|
251
127
|
);
|
|
@@ -322,7 +198,7 @@ function instrumentPrototype(target, methodsToInstrument) {
|
|
|
322
198
|
}
|
|
323
199
|
|
|
324
200
|
// Use the existing wrapper but with instance-specific context/options
|
|
325
|
-
const wrapper = wrapMethodWithSentry(
|
|
201
|
+
const wrapper = wrapMethodWithSentry.wrapMethodWithSentry(
|
|
326
202
|
{
|
|
327
203
|
options: instanceOptions,
|
|
328
204
|
context: instanceContext,
|
|
@@ -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 isThenable,\n type Scope,\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';\nimport { copyExecutionContext } from './utils/copyExecutionContext';\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\ntype UncheckedMethod = (...args: any[]) => any;\ntype OriginalMethod = UncheckedMethod;\n\nfunction wrapMethodWithSentry<T extends OriginalMethod>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n noMark?: true,\n): T {\n if (isInstrumented(handler)) {\n return handler;\n }\n\n if (!noMark) {\n markAsInstrumented(handler);\n }\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\n const wrappedFunction = (scope: Scope): 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 = 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 const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(\n (res: unknown) => {\n waitUntil?.(flush(2000));\n return res;\n },\n (e: unknown) => {\n captureException(e, {\n mechanism: {\n type: 'auto.faas.cloudflare.durable_object',\n handled: false,\n },\n });\n waitUntil?.(flush(2000));\n throw e;\n },\n );\n } else {\n waitUntil?.(flush(2000));\n return result;\n }\n } catch (e) {\n captureException(e, {\n mechanism: {\n type: 'auto.faas.cloudflare.durable_object',\n handled: false,\n },\n });\n waitUntil?.(flush(2000));\n throw e;\n }\n }\n\n const attributes = wrapperOptions.spanOp\n ? {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.durable_object',\n }\n : {};\n\n return startSpan({ name: wrapperOptions.spanName, attributes }, () => {\n try {\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(\n (res: unknown) => {\n waitUntil?.(flush(2000));\n return res;\n },\n (e: unknown) => {\n captureException(e, {\n mechanism: {\n type: 'auto.faas.cloudflare.durable_object',\n handled: false,\n },\n });\n waitUntil?.(flush(2000));\n throw e;\n },\n );\n } else {\n waitUntil?.(flush(2000));\n return result;\n }\n } catch (e) {\n captureException(e, {\n mechanism: {\n type: 'auto.faas.cloudflare.durable_object',\n handled: false,\n },\n });\n waitUntil?.(flush(2000));\n throw e;\n }\n });\n };\n\n return sentryWithScope(wrappedFunction);\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, [ctx, env]) {\n setAsyncLocalStorageAsyncContextStrategy();\n const context = copyExecutionContext(ctx);\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: 'auto.faas.cloudflare.durable_object_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 value as UncheckedMethod,\n );\n }\n }\n\n // Store context and options on the instance for prototype methods to access\n Object.defineProperty(obj, '__SENTRY_CONTEXT__', {\n value: context,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(obj, '__SENTRY_OPTIONS__', {\n value: options,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n if (options?.instrumentPrototypeMethods) {\n instrumentPrototype(target, options.instrumentPrototypeMethods);\n }\n\n return obj;\n },\n });\n}\n\nfunction instrumentPrototype<T extends NewableFunction>(target: T, methodsToInstrument: boolean | string[]): void {\n const proto = target.prototype;\n\n // Get all methods from the prototype chain\n const methodNames = new Set<string>();\n let current = proto;\n\n while (current && current !== Object.prototype) {\n Object.getOwnPropertyNames(current).forEach(name => {\n if (name !== 'constructor' && typeof (current as Record<string, unknown>)[name] === 'function') {\n methodNames.add(name);\n }\n });\n current = Object.getPrototypeOf(current);\n }\n\n // Create a set for efficient lookups when methodsToInstrument is an array\n const methodsToInstrumentSet = Array.isArray(methodsToInstrument) ? new Set(methodsToInstrument) : null;\n\n // Instrument each method on the prototype\n methodNames.forEach(methodName => {\n const originalMethod = (proto as Record<string, unknown>)[methodName];\n\n if (!originalMethod || isInstrumented(originalMethod)) {\n return;\n }\n\n // If methodsToInstrument is an array, only instrument methods in that set\n if (methodsToInstrumentSet && !methodsToInstrumentSet.has(methodName)) {\n return;\n }\n\n // Create a wrapper that gets context/options from the instance at runtime\n const wrappedMethod = function (this: unknown, ...args: unknown[]): unknown {\n const thisWithSentry = this as {\n __SENTRY_CONTEXT__: DurableObjectState;\n __SENTRY_OPTIONS__: CloudflareOptions;\n };\n const instanceContext = thisWithSentry.__SENTRY_CONTEXT__;\n const instanceOptions = thisWithSentry.__SENTRY_OPTIONS__;\n\n if (!instanceOptions) {\n // Fallback to original method if no Sentry data found\n return (originalMethod as UncheckedMethod).apply(this, args);\n }\n\n // Use the existing wrapper but with instance-specific context/options\n const wrapper = wrapMethodWithSentry(\n {\n options: instanceOptions,\n context: instanceContext,\n spanName: methodName,\n spanOp: 'rpc',\n },\n originalMethod as UncheckedMethod,\n undefined,\n true, // noMark = true since we'll mark the prototype method\n );\n\n return wrapper.apply(this, args);\n };\n\n markAsInstrumented(wrappedMethod);\n\n // Replace the prototype method\n Object.defineProperty(proto, methodName, {\n value: wrappedMethod,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n });\n}\n"],"names":["isInstrumented","markAsInstrumented","getClient","withScope","withIsolationScope","init","isThenable","flush","captureException","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","setAsyncLocalStorageAsyncContextStrategy","copyExecutionContext","options","getFinalOptions","wrapRequestHandler"],"mappings":";;;;;;;;;;AAAA;;AAiCA,SAAS,oBAAoB;AAC7B,EAAE,cAAc;AAChB,EAAE,OAAO;AACT,EAAE,QAAQ;AACV,EAAE,MAAM;AACR,EAAK;AACL,EAAE,IAAIA,yBAAc,CAAC,OAAO,CAAC,EAAE;AAC/B,IAAI,OAAO,OAAO;AAClB,EAAE;;AAEF,EAAE,IAAI,CAAC,MAAM,EAAE;AACf,IAAIC,6BAAkB,CAAC,OAAO,CAAC;AAC/B,EAAE;;AAEF,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE;AAC5B,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAiB;AAChD,MAAM,MAAM,aAAA,GAAgBC,cAAS,EAAE;AACvC;AACA,MAAM,MAAM,eAAA,GAAkB,gBAAgBC,cAAA,GAAYC,uBAAkB;;AAE5E,MAAM,MAAM,eAAA,GAAkB,CAAC,KAAK,KAAqB;AACzD;AACA;AACA;AACA,QAAQ,MAAM,OAAA,GAAU,cAAc,CAAC,OAAA;;AAEvC,QAAQ,MAAM,SAAA,GAAY,OAAO,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC;;AAE7D,QAAQ,MAAM,aAAA,GAAgB,KAAK,CAAC,SAAS,EAAE;AAC/C,QAAQ,IAAI,CAAC,aAAa,EAAE;AAC5B,UAAU,MAAM,MAAA,GAASC,QAAI,CAAC,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,OAAA,EAAS,CAAC;AAC1E,UAAU,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC;AACjC,QAAQ;;AAER,QAAQ,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;AACtC,UAAU,IAAI;AACd,YAAY,IAAI,QAAQ,EAAE;AAC1B,cAAc,QAAQ,CAAC,GAAG,IAAI,CAAC;AAC/B,YAAY;AACZ,YAAY,MAAM,MAAA,GAAS,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;;AAE/D,YAAY,IAAIC,eAAU,CAAC,MAAM,CAAC,EAAE;AACpC,cAAc,OAAO,MAAM,CAAC,IAAI;AAChC,gBAAgB,CAAC,GAAG,KAAc;AAClC,kBAAkB,SAAS,GAAGC,UAAK,CAAC,IAAI,CAAC,CAAC;AAC1C,kBAAkB,OAAO,GAAG;AAC5B,gBAAgB,CAAC;AACjB,gBAAgB,CAAC,CAAC,KAAc;AAChC,kBAAkBC,qBAAgB,CAAC,CAAC,EAAE;AACtC,oBAAoB,SAAS,EAAE;AAC/B,sBAAsB,IAAI,EAAE,qCAAqC;AACjE,sBAAsB,OAAO,EAAE,KAAK;AACpC,qBAAqB;AACrB,mBAAmB,CAAC;AACpB,kBAAkB,SAAS,GAAGD,UAAK,CAAC,IAAI,CAAC,CAAC;AAC1C,kBAAkB,MAAM,CAAC;AACzB,gBAAgB,CAAC;AACjB,eAAe;AACf,YAAY,OAAO;AACnB,cAAc,SAAS,GAAGA,UAAK,CAAC,IAAI,CAAC,CAAC;AACtC,cAAc,OAAO,MAAM;AAC3B,YAAY;AACZ,UAAU,CAAA,CAAE,OAAO,CAAC,EAAE;AACtB,YAAYC,qBAAgB,CAAC,CAAC,EAAE;AAChC,cAAc,SAAS,EAAE;AACzB,gBAAgB,IAAI,EAAE,qCAAqC;AAC3D,gBAAgB,OAAO,EAAE,KAAK;AAC9B,eAAe;AACf,aAAa,CAAC;AACd,YAAY,SAAS,GAAGD,UAAK,CAAC,IAAI,CAAC,CAAC;AACpC,YAAY,MAAM,CAAC;AACnB,UAAU;AACV,QAAQ;;AAER,QAAQ,MAAM,UAAA,GAAa,cAAc,CAAC;AAC1C,YAAY;AACZ,cAAc,CAACE,iCAA4B,GAAG,cAAc,CAAC,MAAM;AACnE,cAAc,CAACC,qCAAgC,GAAG,qCAAqC;AACvF;AACA,YAAY,EAAE;;AAEd,QAAQ,OAAOC,cAAS,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,QAAQ,EAAE,UAAA,EAAY,EAAE,MAAM;AAC9E,UAAU,IAAI;AACd,YAAY,MAAM,MAAA,GAAS,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;;AAE/D,YAAY,IAAIL,eAAU,CAAC,MAAM,CAAC,EAAE;AACpC,cAAc,OAAO,MAAM,CAAC,IAAI;AAChC,gBAAgB,CAAC,GAAG,KAAc;AAClC,kBAAkB,SAAS,GAAGC,UAAK,CAAC,IAAI,CAAC,CAAC;AAC1C,kBAAkB,OAAO,GAAG;AAC5B,gBAAgB,CAAC;AACjB,gBAAgB,CAAC,CAAC,KAAc;AAChC,kBAAkBC,qBAAgB,CAAC,CAAC,EAAE;AACtC,oBAAoB,SAAS,EAAE;AAC/B,sBAAsB,IAAI,EAAE,qCAAqC;AACjE,sBAAsB,OAAO,EAAE,KAAK;AACpC,qBAAqB;AACrB,mBAAmB,CAAC;AACpB,kBAAkB,SAAS,GAAGD,UAAK,CAAC,IAAI,CAAC,CAAC;AAC1C,kBAAkB,MAAM,CAAC;AACzB,gBAAgB,CAAC;AACjB,eAAe;AACf,YAAY,OAAO;AACnB,cAAc,SAAS,GAAGA,UAAK,CAAC,IAAI,CAAC,CAAC;AACtC,cAAc,OAAO,MAAM;AAC3B,YAAY;AACZ,UAAU,CAAA,CAAE,OAAO,CAAC,EAAE;AACtB,YAAYC,qBAAgB,CAAC,CAAC,EAAE;AAChC,cAAc,SAAS,EAAE;AACzB,gBAAgB,IAAI,EAAE,qCAAqC;AAC3D,gBAAgB,OAAO,EAAE,KAAK;AAC9B,eAAe;AACf,aAAa,CAAC;AACd,YAAY,SAAS,GAAGD,UAAK,CAAC,IAAI,CAAC,CAAC;AACpC,YAAY,MAAM,CAAC;AACnB,UAAU;AACV,QAAQ,CAAC,CAAC;AACV,MAAM,CAAC;;AAEP,MAAM,OAAO,eAAe,CAAC,eAAe,CAAC;AAC7C,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS;;AAIhB,CAAE,eAAe,EAAiC,kBAAkB,EAAQ;AAC5E,EAAE,OAAO,IAAI,KAAK,CAAC,kBAAkB,EAAE;AACvC,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;AAClC,MAAMK,8CAAwC,EAAE;AAChD,MAAM,MAAM,OAAA,GAAUC,yCAAoB,CAAC,GAAG,CAAC;;AAE/C,MAAM,MAAMC,SAAA,GAAUC,uBAAe,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;;AAEhE,MAAM,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;;AAE1C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,MAAM,IAAI,GAAG,CAAC,SAAS,OAAO,GAAG,CAAC,KAAA,KAAU,UAAA,IAAc,CAACf,yBAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AACtF,QAAQ,GAAG,CAAC,KAAA,GAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE;AACzC,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;AACvC,YAAY,OAAOgB,0BAAkB,CAAC,WAAEF,SAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE;AAC9E,cAAc,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AAClD,aAAa;AACb,UAAU,CAAC;AACX,SAAS,CAAC;;AAEV,QAAQb,6BAAkB,CAAC,GAAG,CAAC,KAAK,CAAC;AACrC,MAAM;;AAEN,MAAM,IAAI,GAAG,CAAC,KAAA,IAAS,OAAO,GAAG,CAAC,KAAA,KAAU,UAAU,EAAE;AACxD,QAAQ,GAAG,CAAC,KAAA,GAAQ,oBAAoB,CAAC,WAAEa,SAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAA,EAAS,EAAE,GAAG,CAAC,KAAK,CAAC;AAC5F,MAAM;;AAEN,MAAM,IAAI,GAAG,CAAC,gBAAA,IAAoB,OAAO,GAAG,CAAC,gBAAA,KAAqB,UAAU,EAAE;AAC9E,QAAQ,GAAG,CAAC,gBAAA,GAAmB,oBAAoB;AACnD,UAAU,WAAEA,SAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,oBAAoB;AAC5D,UAAU,GAAG,CAAC,gBAAgB;AAC9B,SAAS;AACT,MAAM;;AAEN,MAAM,IAAI,GAAG,CAAC,cAAA,IAAkB,OAAO,GAAG,CAAC,cAAA,KAAmB,UAAU,EAAE;AAC1E,QAAQ,GAAG,CAAC,cAAA,GAAiB,oBAAoB,CAAC,WAAEA,SAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAA,EAAkB,EAAE,GAAG,CAAC,cAAc,CAAC;AACvH,MAAM;;AAEN,MAAM,IAAI,GAAG,CAAC,cAAA,IAAkB,OAAO,GAAG,CAAC,cAAA,KAAmB,UAAU,EAAE;AAC1E,QAAQ,GAAG,CAAC,cAAA,GAAiB,oBAAoB;AACjD,UAAU,WAAEA,SAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,kBAAkB;AAC1D,UAAU,GAAG,CAAC,cAAc;AAC5B,UAAU,CAAC,CAAC,EAAE,KAAK;AACnB,YAAYN,qBAAgB,CAAC,KAAK,EAAE;AACpC,cAAc,SAAS,EAAE;AACzB,gBAAgB,IAAI,EAAE,+CAA+C;AACrE,gBAAgB,OAAO,EAAE,KAAK;AAC9B,eAAe;AACf,aAAa,CAAC;AACd,SAAS;AACT,MAAM;;AAEN,MAAM,KAAK,MAAM,MAAA,IAAU,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE;AAC5D,QAAQ;AACR,UAAU,MAAA,KAAW,OAAA;AACrB,UAAU,MAAA,KAAW,OAAA;AACrB,UAAU,MAAA,KAAW,gBAAA;AACrB,UAAU,MAAA,KAAW,gBAAA;AACrB,UAAU,WAAW;AACrB,UAAU;AACV,UAAU;AACV,QAAQ;;AAER;AACA,QAAQ,MAAM,QAAQ,CAAC,MAAY,MAAM,CAAA;AACzC,QAAQ,IAAI,OAAO,KAAA,KAAU,UAAU,EAAE;AACzC;AACA,UAAU,CAAC,GAAA,GAAY,MAAM,CAAA,GAAI,oBAAoB;AACrD,YAAY,WAAEM,SAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAA,EAAO;AACjE,YAAY,KAAA;AACZ,WAAW;AACX,QAAQ;AACR,MAAM;;AAEN;AACA,MAAM,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE;AACvD,QAAQ,KAAK,EAAE,OAAO;AACtB,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,YAAY,EAAE,KAAK;AAC3B,OAAO,CAAC;;AAER,MAAM,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE;AACvD,QAAQ,KAAK,EAAEA,SAAO;AACtB,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,YAAY,EAAE,KAAK;AAC3B,OAAO,CAAC;;AAER,MAAM,IAAIA,SAAO,EAAE,0BAA0B,EAAE;AAC/C,QAAQ,mBAAmB,CAAC,MAAM,EAAEA,SAAO,CAAC,0BAA0B,CAAC;AACvE,MAAM;;AAEN,MAAM,OAAO,GAAG;AAChB,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;AAEA,SAAS,mBAAmB,CAA4B,MAAM,EAAK,mBAAmB,EAA4B;AAClH,EAAE,MAAM,KAAA,GAAQ,MAAM,CAAC,SAAS;;AAEhC;AACA,EAAE,MAAM,WAAA,GAAc,IAAI,GAAG,EAAU;AACvC,EAAE,IAAI,OAAA,GAAU,KAAK;;AAErB,EAAE,OAAO,OAAA,IAAW,YAAY,MAAM,CAAC,SAAS,EAAE;AAClD,IAAI,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,IAAA,IAAQ;AACxD,MAAM,IAAI,IAAA,KAAS,iBAAiB,OAAO,CAAC,OAAA,GAAoC,IAAI,CAAA,KAAM,UAAU,EAAE;AACtG,QAAQ,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AAC7B,MAAM;AACN,IAAI,CAAC,CAAC;AACN,IAAI,UAAU,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC;AAC5C,EAAE;;AAEF;AACA,EAAE,MAAM,sBAAA,GAAyB,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAA,GAAI,IAAI,GAAG,CAAC,mBAAmB,CAAA,GAAI,IAAI;;AAEzG;AACA,EAAE,WAAW,CAAC,OAAO,CAAC,cAAc;AACpC,IAAI,MAAM,iBAAiB,CAAC,QAAkC,UAAU,CAAC;;AAEzE,IAAI,IAAI,CAAC,cAAA,IAAkBd,yBAAc,CAAC,cAAc,CAAC,EAAE;AAC3D,MAAM;AACN,IAAI;;AAEJ;AACA,IAAI,IAAI,sBAAA,IAA0B,CAAC,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;AAC3E,MAAM;AACN,IAAI;;AAEJ;AACA,IAAI,MAAM,gBAAgB,WAAyB,GAAG,IAAI,EAAsB;AAChF,MAAM,MAAM,cAAA,GAAiB;;AAGvB;AACN,MAAM,MAAM,eAAA,GAAkB,cAAc,CAAC,kBAAkB;AAC/D,MAAM,MAAM,eAAA,GAAkB,cAAc,CAAC,kBAAkB;;AAE/D,MAAM,IAAI,CAAC,eAAe,EAAE;AAC5B;AACA,QAAQ,OAAO,CAAC,cAAA,GAAmC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AACpE,MAAM;;AAEN;AACA,MAAM,MAAM,OAAA,GAAU,oBAAoB;AAC1C,QAAQ;AACR,UAAU,OAAO,EAAE,eAAe;AAClC,UAAU,OAAO,EAAE,eAAe;AAClC,UAAU,QAAQ,EAAE,UAAU;AAC9B,UAAU,MAAM,EAAE,KAAK;AACvB,SAAS;AACT,QAAQ,cAAA;AACR,QAAQ,SAAS;AACjB,QAAQ,IAAI;AACZ,OAAO;;AAEP,MAAM,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AACtC,IAAI,CAAC;;AAEL,IAAIC,6BAAkB,CAAC,aAAa,CAAC;;AAErC;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE;AAC7C,MAAM,KAAK,EAAE,aAAa;AAC1B,MAAM,UAAU,EAAE,KAAK;AACvB,MAAM,QAAQ,EAAE,IAAI;AACpB,MAAM,YAAY,EAAE,IAAI;AACxB,KAAK,CAAC;AACN,EAAE,CAAC,CAAC;AACJ;;;;"}
|
|
1
|
+
{"version":3,"file":"durableobject.js","sources":["../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport { captureException } 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 { instrumentContext } from './utils/instrumentContext';\nimport type { UncheckedMethod } from './wrapMethodWithSentry';\nimport { wrapMethodWithSentry } from './wrapMethodWithSentry';\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, [ctx, env]) {\n setAsyncLocalStorageAsyncContextStrategy();\n const context = instrumentContext(ctx);\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: 'auto.faas.cloudflare.durable_object_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 value as UncheckedMethod,\n );\n }\n }\n\n // Store context and options on the instance for prototype methods to access\n Object.defineProperty(obj, '__SENTRY_CONTEXT__', {\n value: context,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(obj, '__SENTRY_OPTIONS__', {\n value: options,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n if (options?.instrumentPrototypeMethods) {\n instrumentPrototype(target, options.instrumentPrototypeMethods);\n }\n\n return obj;\n },\n });\n}\n\nfunction instrumentPrototype<T extends NewableFunction>(target: T, methodsToInstrument: boolean | string[]): void {\n const proto = target.prototype;\n\n // Get all methods from the prototype chain\n const methodNames = new Set<string>();\n let current = proto;\n\n while (current && current !== Object.prototype) {\n Object.getOwnPropertyNames(current).forEach(name => {\n if (name !== 'constructor' && typeof (current as Record<string, unknown>)[name] === 'function') {\n methodNames.add(name);\n }\n });\n current = Object.getPrototypeOf(current);\n }\n\n // Create a set for efficient lookups when methodsToInstrument is an array\n const methodsToInstrumentSet = Array.isArray(methodsToInstrument) ? new Set(methodsToInstrument) : null;\n\n // Instrument each method on the prototype\n methodNames.forEach(methodName => {\n const originalMethod = (proto as Record<string, unknown>)[methodName];\n\n if (!originalMethod || isInstrumented(originalMethod)) {\n return;\n }\n\n // If methodsToInstrument is an array, only instrument methods in that set\n if (methodsToInstrumentSet && !methodsToInstrumentSet.has(methodName)) {\n return;\n }\n\n // Create a wrapper that gets context/options from the instance at runtime\n const wrappedMethod = function (this: unknown, ...args: unknown[]): unknown {\n const thisWithSentry = this as {\n __SENTRY_CONTEXT__: DurableObjectState;\n __SENTRY_OPTIONS__: CloudflareOptions;\n };\n const instanceContext = thisWithSentry.__SENTRY_CONTEXT__;\n const instanceOptions = thisWithSentry.__SENTRY_OPTIONS__;\n\n if (!instanceOptions) {\n // Fallback to original method if no Sentry data found\n return (originalMethod as UncheckedMethod).apply(this, args);\n }\n\n // Use the existing wrapper but with instance-specific context/options\n const wrapper = wrapMethodWithSentry(\n {\n options: instanceOptions,\n context: instanceContext,\n spanName: methodName,\n spanOp: 'rpc',\n },\n originalMethod as UncheckedMethod,\n undefined,\n true, // noMark = true since we'll mark the prototype method\n );\n\n return wrapper.apply(this, args);\n };\n\n markAsInstrumented(wrappedMethod);\n\n // Replace the prototype method\n Object.defineProperty(proto, methodName, {\n value: wrappedMethod,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n });\n}\n"],"names":["setAsyncLocalStorageAsyncContextStrategy","instrumentContext","options","getFinalOptions","isInstrumented","wrapRequestHandler","markAsInstrumented","wrapMethodWithSentry","captureException"],"mappings":"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"}
|
package/build/cjs/handler.js
CHANGED
|
@@ -8,7 +8,7 @@ const options = require('./options.js');
|
|
|
8
8
|
const request = require('./request.js');
|
|
9
9
|
const scopeUtils = require('./scope-utils.js');
|
|
10
10
|
const sdk = require('./sdk.js');
|
|
11
|
-
const
|
|
11
|
+
const instrumentContext = require('./utils/instrumentContext.js');
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Wrapper for Cloudflare handlers.
|
|
@@ -32,7 +32,7 @@ function withSentry
|
|
|
32
32
|
handler.fetch = new Proxy(handler.fetch, {
|
|
33
33
|
apply(target, thisArg, args) {
|
|
34
34
|
const [request$1, env, ctx] = args;
|
|
35
|
-
const context =
|
|
35
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
36
36
|
args[2] = context;
|
|
37
37
|
|
|
38
38
|
const options$1 = options.getFinalOptions(optionsCallback(env), env);
|
|
@@ -68,7 +68,7 @@ function withSentry
|
|
|
68
68
|
handler.scheduled = new Proxy(handler.scheduled, {
|
|
69
69
|
apply(target, thisArg, args) {
|
|
70
70
|
const [event, env, ctx] = args;
|
|
71
|
-
const context =
|
|
71
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
72
72
|
args[2] = context;
|
|
73
73
|
|
|
74
74
|
return core.withIsolationScope(isolationScope => {
|
|
@@ -114,7 +114,7 @@ function withSentry
|
|
|
114
114
|
handler.email = new Proxy(handler.email, {
|
|
115
115
|
apply(target, thisArg, args) {
|
|
116
116
|
const [emailMessage, env, ctx] = args;
|
|
117
|
-
const context =
|
|
117
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
118
118
|
args[2] = context;
|
|
119
119
|
|
|
120
120
|
return core.withIsolationScope(isolationScope => {
|
|
@@ -158,7 +158,7 @@ function withSentry
|
|
|
158
158
|
handler.queue = new Proxy(handler.queue, {
|
|
159
159
|
apply(target, thisArg, args) {
|
|
160
160
|
const [batch, env, ctx] = args;
|
|
161
|
-
const context =
|
|
161
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
162
162
|
args[2] = context;
|
|
163
163
|
|
|
164
164
|
return core.withIsolationScope(isolationScope => {
|
|
@@ -210,7 +210,7 @@ function withSentry
|
|
|
210
210
|
handler.tail = new Proxy(handler.tail, {
|
|
211
211
|
apply(target, thisArg, args) {
|
|
212
212
|
const [, env, ctx] = args;
|
|
213
|
-
const context =
|
|
213
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
214
214
|
args[2] = context;
|
|
215
215
|
|
|
216
216
|
return core.withIsolationScope(async isolationScope => {
|
package/build/cjs/handler.js.map
CHANGED
|
@@ -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 { getHonoIntegration } from './integrations/hono';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandler } from './request';\nimport { addCloudResourceContext } from './scope-utils';\nimport { init } from './sdk';\nimport { copyExecutionContext } from './utils/copyExecutionContext';\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<\n Env = unknown,\n QueueHandlerMessage = unknown,\n CfHostMetadata = unknown,\n T extends ExportedHandler<Env, QueueHandlerMessage, CfHostMetadata> = ExportedHandler<\n Env,\n QueueHandlerMessage,\n CfHostMetadata\n >,\n>(optionsCallback: (env: Env) => CloudflareOptions | undefined, handler: T): T {\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, ctx] = args;\n const context = copyExecutionContext(ctx);\n args[2] = context;\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, context] = args;\n\n getHonoIntegration()?.handleHonoException(err, context);\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, ctx] = args;\n const context = copyExecutionContext(ctx);\n args[2] = context;\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.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: 'auto.faas.cloudflare.scheduled' } });\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, ctx] = args;\n const context = copyExecutionContext(ctx);\n args[2] = context;\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.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: 'auto.faas.cloudflare.email' } });\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, ctx] = args;\n const context = copyExecutionContext(ctx);\n args[2] = context;\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(\n (acc, message) => acc + message.attempts - 1,\n 0,\n ),\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: 'auto.faas.cloudflare.queue' } });\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, ctx] = args;\n const context = copyExecutionContext(ctx);\n args[2] = context;\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: 'auto.faas.cloudflare.tail' } });\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 {\n // Do not console anything here, we don't want to spam the console with errors\n }\n\n return handler;\n}\n"],"names":["setAsyncLocalStorageAsyncContextStrategy","isInstrumented","request","copyExecutionContext","options","getFinalOptions","wrapRequestHandler","markAsInstrumented","getHonoIntegration","withIsolationScope","init","addCloudResourceContext","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","captureException","flush","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"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 { getHonoIntegration } from './integrations/hono';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandler } from './request';\nimport { addCloudResourceContext } from './scope-utils';\nimport { init } from './sdk';\nimport { instrumentContext } from './utils/instrumentContext';\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<\n Env = unknown,\n QueueHandlerMessage = unknown,\n CfHostMetadata = unknown,\n T extends ExportedHandler<Env, QueueHandlerMessage, CfHostMetadata> = ExportedHandler<\n Env,\n QueueHandlerMessage,\n CfHostMetadata\n >,\n>(optionsCallback: (env: Env) => CloudflareOptions | undefined, handler: T): T {\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, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\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, context] = args;\n\n getHonoIntegration()?.handleHonoException(err, context);\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, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\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.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: 'auto.faas.cloudflare.scheduled' } });\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, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\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.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: 'auto.faas.cloudflare.email' } });\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, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\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(\n (acc, message) => acc + message.attempts - 1,\n 0,\n ),\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: 'auto.faas.cloudflare.queue' } });\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, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\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: 'auto.faas.cloudflare.tail' } });\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 {\n // Do not console anything here, we don't want to spam the console with errors\n }\n\n return handler;\n}\n"],"names":["setAsyncLocalStorageAsyncContextStrategy","isInstrumented","request","instrumentContext","options","getFinalOptions","wrapRequestHandler","markAsInstrumented","getHonoIntegration","withIsolationScope","init","addCloudResourceContext","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","captureException","flush","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const core = require('@sentry/core');
|
|
4
|
+
|
|
5
|
+
const STORAGE_METHODS_TO_INSTRUMENT = ['get', 'put', 'delete', 'list'] ;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Instruments DurableObjectStorage methods with Sentry spans.
|
|
9
|
+
*
|
|
10
|
+
* Wraps the following async methods:
|
|
11
|
+
* - get, put, delete, list (KV API)
|
|
12
|
+
*
|
|
13
|
+
* @param storage - The DurableObjectStorage instance to instrument
|
|
14
|
+
* @returns An instrumented DurableObjectStorage instance
|
|
15
|
+
*/
|
|
16
|
+
function instrumentDurableObjectStorage(storage) {
|
|
17
|
+
return new Proxy(storage, {
|
|
18
|
+
get(target, prop, receiver) {
|
|
19
|
+
const original = Reflect.get(target, prop, receiver);
|
|
20
|
+
|
|
21
|
+
if (typeof original !== 'function') {
|
|
22
|
+
return original;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const methodName = prop ;
|
|
26
|
+
if (!STORAGE_METHODS_TO_INSTRUMENT.includes(methodName )) {
|
|
27
|
+
return (original ).bind(target);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return function ( ...args) {
|
|
31
|
+
return core.startSpan(
|
|
32
|
+
{
|
|
33
|
+
// Use underscore naming to match Cloudflare's native instrumentation (e.g., "durable_object_storage_get")
|
|
34
|
+
name: `durable_object_storage_${methodName}`,
|
|
35
|
+
op: 'db',
|
|
36
|
+
attributes: {
|
|
37
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.durable_object',
|
|
38
|
+
'db.system.name': 'cloudflare.durable_object.storage',
|
|
39
|
+
'db.operation.name': methodName,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
() => {
|
|
43
|
+
return (original ).apply(target, args);
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
exports.instrumentDurableObjectStorage = instrumentDurableObjectStorage;
|
|
52
|
+
//# sourceMappingURL=instrumentDurableObjectStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentDurableObjectStorage.js","sources":["../../../src/instrumentations/instrumentDurableObjectStorage.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/core';\n\nconst STORAGE_METHODS_TO_INSTRUMENT = ['get', 'put', 'delete', 'list'] as const;\n\ntype StorageMethod = (typeof STORAGE_METHODS_TO_INSTRUMENT)[number];\n\n/**\n * Instruments DurableObjectStorage methods with Sentry spans.\n *\n * Wraps the following async methods:\n * - get, put, delete, list (KV API)\n *\n * @param storage - The DurableObjectStorage instance to instrument\n * @returns An instrumented DurableObjectStorage instance\n */\nexport function instrumentDurableObjectStorage(storage: DurableObjectStorage): DurableObjectStorage {\n return new Proxy(storage, {\n get(target, prop, receiver) {\n const original = Reflect.get(target, prop, receiver);\n\n if (typeof original !== 'function') {\n return original;\n }\n\n const methodName = prop as string;\n if (!STORAGE_METHODS_TO_INSTRUMENT.includes(methodName as StorageMethod)) {\n return (original as (...args: unknown[]) => unknown).bind(target);\n }\n\n return function (this: unknown, ...args: unknown[]) {\n return startSpan(\n {\n // Use underscore naming to match Cloudflare's native instrumentation (e.g., \"durable_object_storage_get\")\n name: `durable_object_storage_${methodName}`,\n op: 'db',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.durable_object',\n 'db.system.name': 'cloudflare.durable_object.storage',\n 'db.operation.name': methodName,\n },\n },\n () => {\n return (original as (...args: unknown[]) => unknown).apply(target, args);\n },\n );\n };\n },\n });\n}\n"],"names":["startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN"],"mappings":";;;;AAGA,MAAM,6BAAA,GAAgC,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAA;;AAIrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,8BAA8B,CAAC,OAAO,EAA8C;AACpG,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE;AAC5B,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;AAChC,MAAM,MAAM,QAAA,GAAW,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;;AAE1D,MAAM,IAAI,OAAO,QAAA,KAAa,UAAU,EAAE;AAC1C,QAAQ,OAAO,QAAQ;AACvB,MAAM;;AAEN,MAAM,MAAM,UAAA,GAAa,IAAA;AACzB,MAAM,IAAI,CAAC,6BAA6B,CAAC,QAAQ,CAAC,UAAA,EAA4B,EAAE;AAChF,QAAQ,OAAO,CAAC,QAAA,GAA6C,IAAI,CAAC,MAAM,CAAC;AACzE,MAAM;;AAEN,MAAM,OAAO,WAAyB,GAAG,IAAI,EAAa;AAC1D,QAAQ,OAAOA,cAAS;AACxB,UAAU;AACV;AACA,YAAY,IAAI,EAAE,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAA;AACA,YAAA,EAAA,EAAA,IAAA;AACA,YAAA,UAAA,EAAA;AACA,cAAA,CAAAC,qCAAA,GAAA,mCAAA;AACA,cAAA,gBAAA,EAAA,mCAAA;AACA,cAAA,mBAAA,EAAA,UAAA;AACA,aAAA;AACA,WAAA;AACA,UAAA,MAAA;AACA,YAAA,OAAA,CAAA,QAAA,GAAA,KAAA,CAAA,MAAA,EAAA,IAAA,CAAA;AACA,UAAA,CAAA;AACA,SAAA;AACA,MAAA,CAAA;AACA,IAAA,CAAA;AACA,GAAA,CAAA;AACA;;;;"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const instrumentDurableObjectStorage = require('../instrumentations/instrumentDurableObjectStorage.js');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Instruments an execution context or DurableObjectState with Sentry tracing.
|
|
7
|
+
*
|
|
8
|
+
* Creates a copy of the context that:
|
|
9
|
+
* - Allows overriding of methods (e.g., waitUntil)
|
|
10
|
+
* - For DurableObjectState: instruments storage operations (get, put, delete, list, etc.)
|
|
11
|
+
* to create Sentry spans automatically
|
|
12
|
+
*
|
|
13
|
+
* @param ctx - The execution context or DurableObjectState to instrument
|
|
14
|
+
* @returns An instrumented copy of the context
|
|
15
|
+
*/
|
|
16
|
+
function instrumentContext(ctx) {
|
|
17
|
+
if (!ctx) return ctx;
|
|
18
|
+
|
|
19
|
+
const overrides = new Map();
|
|
20
|
+
const contextPrototype = Object.getPrototypeOf(ctx);
|
|
21
|
+
const prototypeMethodNames = Object.getOwnPropertyNames(contextPrototype) ;
|
|
22
|
+
const ownPropertyNames = Object.getOwnPropertyNames(ctx) ;
|
|
23
|
+
const instrumented = new Set(['constructor']);
|
|
24
|
+
const descriptors = [...ownPropertyNames, ...prototypeMethodNames].reduce(
|
|
25
|
+
(prevDescriptors, methodName) => {
|
|
26
|
+
if (instrumented.has(methodName)) return prevDescriptors;
|
|
27
|
+
if (typeof ctx[methodName] !== 'function') return prevDescriptors;
|
|
28
|
+
instrumented.add(methodName);
|
|
29
|
+
const overridableDescriptor = makeOverridableDescriptor(overrides, ctx, methodName);
|
|
30
|
+
return {
|
|
31
|
+
...prevDescriptors,
|
|
32
|
+
[methodName]: overridableDescriptor,
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
{} ,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// Check if this is a DurableObjectState context with a storage property
|
|
39
|
+
// If so, wrap the storage with instrumentation
|
|
40
|
+
if ('storage' in ctx && ctx.storage) {
|
|
41
|
+
const originalStorage = ctx.storage;
|
|
42
|
+
let instrumentedStorage;
|
|
43
|
+
descriptors.storage = {
|
|
44
|
+
configurable: true,
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: () => {
|
|
47
|
+
if (!instrumentedStorage) {
|
|
48
|
+
instrumentedStorage = instrumentDurableObjectStorage.instrumentDurableObjectStorage(originalStorage);
|
|
49
|
+
}
|
|
50
|
+
return instrumentedStorage;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
// Expose the original uninstrumented storage for internal Sentry operations
|
|
54
|
+
// This avoids creating spans for internal storage operations
|
|
55
|
+
descriptors.originalStorage = {
|
|
56
|
+
configurable: true,
|
|
57
|
+
enumerable: false,
|
|
58
|
+
get: () => originalStorage,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return Object.create(ctx, descriptors);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates a property descriptor that allows overriding of a method on the given context object.
|
|
67
|
+
*
|
|
68
|
+
* This descriptor supports property overriding with functions only. It delegates method calls to
|
|
69
|
+
* the provided store if an override exists or to the original method on the context otherwise.
|
|
70
|
+
*
|
|
71
|
+
* @param {OverridesStore<ContextType>} store - The storage for overridden methods specific to the context type.
|
|
72
|
+
* @param {ContextType} ctx - The context object that contains the method to be overridden.
|
|
73
|
+
* @param {keyof ContextType} method - The method on the context object to create the overridable descriptor for.
|
|
74
|
+
* @return {PropertyDescriptor} A property descriptor enabling the overriding of the specified method.
|
|
75
|
+
*/
|
|
76
|
+
function makeOverridableDescriptor(
|
|
77
|
+
store,
|
|
78
|
+
ctx,
|
|
79
|
+
method,
|
|
80
|
+
) {
|
|
81
|
+
return {
|
|
82
|
+
configurable: true,
|
|
83
|
+
enumerable: true,
|
|
84
|
+
set: newValue => {
|
|
85
|
+
if (typeof newValue == 'function') {
|
|
86
|
+
store.set(method, newValue);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
Reflect.set(ctx, method, newValue);
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
get: () => {
|
|
93
|
+
if (store.has(method)) return store.get(method);
|
|
94
|
+
const methodFunction = Reflect.get(ctx, method);
|
|
95
|
+
if (typeof methodFunction !== 'function') return methodFunction;
|
|
96
|
+
// We should do bind() to make sure that the method is bound to the context object - otherwise it will not work
|
|
97
|
+
return methodFunction.bind(ctx);
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
exports.instrumentContext = instrumentContext;
|
|
103
|
+
//# sourceMappingURL=instrumentContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentContext.js","sources":["../../../src/utils/instrumentContext.ts"],"sourcesContent":["import { type DurableObjectState, type DurableObjectStorage, type ExecutionContext } from '@cloudflare/workers-types';\nimport { instrumentDurableObjectStorage } from '../instrumentations/instrumentDurableObjectStorage';\n\ntype ContextType = ExecutionContext | DurableObjectState;\ntype OverridesStore<T extends ContextType> = Map<keyof T, (...args: unknown[]) => unknown>;\n\n/**\n * Instruments an execution context or DurableObjectState with Sentry tracing.\n *\n * Creates a copy of the context that:\n * - Allows overriding of methods (e.g., waitUntil)\n * - For DurableObjectState: instruments storage operations (get, put, delete, list, etc.)\n * to create Sentry spans automatically\n *\n * @param ctx - The execution context or DurableObjectState to instrument\n * @returns An instrumented copy of the context\n */\nexport function instrumentContext<T extends ContextType>(ctx: T): T {\n if (!ctx) return ctx;\n\n const overrides: OverridesStore<T> = new Map();\n const contextPrototype = Object.getPrototypeOf(ctx);\n const prototypeMethodNames = Object.getOwnPropertyNames(contextPrototype) as unknown as (keyof T)[];\n const ownPropertyNames = Object.getOwnPropertyNames(ctx) as unknown as (keyof T)[];\n const instrumented = new Set<unknown>(['constructor']);\n const descriptors: PropertyDescriptorMap = [...ownPropertyNames, ...prototypeMethodNames].reduce(\n (prevDescriptors, methodName) => {\n if (instrumented.has(methodName)) return prevDescriptors;\n if (typeof ctx[methodName] !== 'function') return prevDescriptors;\n instrumented.add(methodName);\n const overridableDescriptor = makeOverridableDescriptor(overrides, ctx, methodName);\n return {\n ...prevDescriptors,\n [methodName]: overridableDescriptor,\n };\n },\n {} as PropertyDescriptorMap,\n );\n\n // Check if this is a DurableObjectState context with a storage property\n // If so, wrap the storage with instrumentation\n if ('storage' in ctx && ctx.storage) {\n const originalStorage = ctx.storage;\n let instrumentedStorage: DurableObjectStorage | undefined;\n descriptors.storage = {\n configurable: true,\n enumerable: true,\n get: () => {\n if (!instrumentedStorage) {\n instrumentedStorage = instrumentDurableObjectStorage(originalStorage);\n }\n return instrumentedStorage;\n },\n };\n // Expose the original uninstrumented storage for internal Sentry operations\n // This avoids creating spans for internal storage operations\n descriptors.originalStorage = {\n configurable: true,\n enumerable: false,\n get: () => originalStorage,\n };\n }\n\n return Object.create(ctx, descriptors);\n}\n\n/**\n * Creates a property descriptor that allows overriding of a method on the given context object.\n *\n * This descriptor supports property overriding with functions only. It delegates method calls to\n * the provided store if an override exists or to the original method on the context otherwise.\n *\n * @param {OverridesStore<ContextType>} store - The storage for overridden methods specific to the context type.\n * @param {ContextType} ctx - The context object that contains the method to be overridden.\n * @param {keyof ContextType} method - The method on the context object to create the overridable descriptor for.\n * @return {PropertyDescriptor} A property descriptor enabling the overriding of the specified method.\n */\nfunction makeOverridableDescriptor<T extends ContextType>(\n store: OverridesStore<T>,\n ctx: T,\n method: keyof T,\n): PropertyDescriptor {\n return {\n configurable: true,\n enumerable: true,\n set: newValue => {\n if (typeof newValue == 'function') {\n store.set(method, newValue);\n return;\n }\n Reflect.set(ctx, method, newValue);\n },\n\n get: () => {\n if (store.has(method)) return store.get(method);\n const methodFunction = Reflect.get(ctx, method);\n if (typeof methodFunction !== 'function') return methodFunction;\n // We should do bind() to make sure that the method is bound to the context object - otherwise it will not work\n return methodFunction.bind(ctx);\n },\n };\n}\n"],"names":["instrumentDurableObjectStorage"],"mappings":"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"}
|
package/build/cjs/workflows.js
CHANGED
|
@@ -4,7 +4,7 @@ const core = require('@sentry/core');
|
|
|
4
4
|
const async = require('./async.js');
|
|
5
5
|
const scopeUtils = require('./scope-utils.js');
|
|
6
6
|
const sdk = require('./sdk.js');
|
|
7
|
-
const
|
|
7
|
+
const instrumentContext = require('./utils/instrumentContext.js');
|
|
8
8
|
|
|
9
9
|
const UUID_REGEX = /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i;
|
|
10
10
|
|
|
@@ -131,7 +131,7 @@ function instrumentWorkflowWithSentry
|
|
|
131
131
|
return new Proxy(WorkFlowClass, {
|
|
132
132
|
construct(target, args, newTarget) {
|
|
133
133
|
const [ctx, env] = args;
|
|
134
|
-
const context =
|
|
134
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
135
135
|
args[0] = context;
|
|
136
136
|
|
|
137
137
|
const options = optionsCallback(env);
|