@sentry/cloudflare 10.46.0 → 10.48.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 +29 -11
- package/build/cjs/durableobject.js.map +1 -1
- package/build/cjs/index.js +2 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/instrument.js +72 -8
- package/build/cjs/instrument.js.map +1 -1
- package/build/cjs/instrumentations/instrumentWorkerEntrypoint.js +101 -0
- package/build/cjs/instrumentations/instrumentWorkerEntrypoint.js.map +1 -0
- package/build/cjs/instrumentations/worker/instrumentEmail.js +14 -12
- package/build/cjs/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentFetch.js +35 -10
- package/build/cjs/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentQueue.js +35 -10
- package/build/cjs/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentScheduled.js +35 -13
- package/build/cjs/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentTail.js +33 -10
- package/build/cjs/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/cjs/request.js +5 -6
- package/build/cjs/request.js.map +1 -1
- package/build/cjs/scope-utils.js.map +1 -1
- package/build/cjs/utils/isCloudflareClass.js +29 -0
- package/build/cjs/utils/isCloudflareClass.js.map +1 -0
- package/build/cjs/withSentry.js +31 -20
- package/build/cjs/withSentry.js.map +1 -1
- package/build/cjs/wrapMethodWithSentry.js +111 -111
- package/build/cjs/wrapMethodWithSentry.js.map +1 -1
- package/build/esm/durableobject.js +30 -12
- package/build/esm/durableobject.js.map +1 -1
- package/build/esm/index.js +1 -1
- package/build/esm/instrument.js +71 -8
- package/build/esm/instrument.js.map +1 -1
- package/build/esm/instrumentations/instrumentWorkerEntrypoint.js +99 -0
- package/build/esm/instrumentations/instrumentWorkerEntrypoint.js.map +1 -0
- package/build/esm/instrumentations/worker/instrumentEmail.js +15 -13
- package/build/esm/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentFetch.js +36 -12
- package/build/esm/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentQueue.js +36 -12
- package/build/esm/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentScheduled.js +36 -15
- package/build/esm/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentTail.js +34 -12
- package/build/esm/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/request.js +5 -6
- package/build/esm/request.js.map +1 -1
- package/build/esm/scope-utils.js.map +1 -1
- package/build/esm/utils/isCloudflareClass.js +27 -0
- package/build/esm/utils/isCloudflareClass.js.map +1 -0
- package/build/esm/withSentry.js +32 -21
- package/build/esm/withSentry.js.map +1 -1
- package/build/esm/wrapMethodWithSentry.js +107 -107
- package/build/esm/wrapMethodWithSentry.js.map +1 -1
- package/build/types/durableobject.d.ts.map +1 -1
- package/build/types/index.d.ts +1 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/instrument.d.ts +15 -4
- package/build/types/instrument.d.ts.map +1 -1
- package/build/types/instrumentations/instrumentWorkerEntrypoint.d.ts +42 -0
- package/build/types/instrumentations/instrumentWorkerEntrypoint.d.ts.map +1 -0
- package/build/types/instrumentations/worker/instrumentEmail.d.ts +2 -1
- package/build/types/instrumentations/worker/instrumentEmail.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentFetch.d.ts +6 -1
- package/build/types/instrumentations/worker/instrumentFetch.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentQueue.d.ts +6 -1
- package/build/types/instrumentations/worker/instrumentQueue.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentScheduled.d.ts +6 -1
- package/build/types/instrumentations/worker/instrumentScheduled.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentTail.d.ts +6 -1
- package/build/types/instrumentations/worker/instrumentTail.d.ts.map +1 -1
- package/build/types/request.d.ts +3 -3
- package/build/types/request.d.ts.map +1 -1
- package/build/types/scope-utils.d.ts +2 -2
- package/build/types/scope-utils.d.ts.map +1 -1
- package/build/types/utils/isCloudflareClass.d.ts +30 -0
- package/build/types/utils/isCloudflareClass.d.ts.map +1 -0
- package/build/types/withSentry.d.ts +3 -2
- package/build/types/withSentry.d.ts.map +1 -1
- package/build/types-ts3.8/index.d.ts +1 -1
- package/build/types-ts3.8/instrument.d.ts +15 -4
- package/build/types-ts3.8/instrumentations/instrumentWorkerEntrypoint.d.ts +42 -0
- package/build/types-ts3.8/instrumentations/worker/instrumentEmail.d.ts +2 -1
- package/build/types-ts3.8/instrumentations/worker/instrumentFetch.d.ts +6 -1
- package/build/types-ts3.8/instrumentations/worker/instrumentQueue.d.ts +6 -1
- package/build/types-ts3.8/instrumentations/worker/instrumentScheduled.d.ts +6 -1
- package/build/types-ts3.8/instrumentations/worker/instrumentTail.d.ts +6 -1
- package/build/types-ts3.8/request.d.ts +3 -3
- package/build/types-ts3.8/scope-utils.d.ts +2 -2
- package/build/types-ts3.8/utils/isCloudflareClass.d.ts +30 -0
- package/build/types-ts3.8/withSentry.d.ts +3 -2
- package/package.json +3 -3
|
@@ -22,128 +22,128 @@ function wrapMethodWithSentry(
|
|
|
22
22
|
callback,
|
|
23
23
|
noMark,
|
|
24
24
|
) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
currentClient = client;
|
|
55
|
-
}
|
|
25
|
+
return instrument.ensureInstrumented(
|
|
26
|
+
handler,
|
|
27
|
+
original =>
|
|
28
|
+
new Proxy(original, {
|
|
29
|
+
apply(target, thisArg, args) {
|
|
30
|
+
const currentClient = core.getClient();
|
|
31
|
+
// if a client is already set, use withScope, otherwise use withIsolationScope
|
|
32
|
+
const sentryWithScope = currentClient ? core.withScope : core.withIsolationScope;
|
|
33
|
+
|
|
34
|
+
const wrappedFunction = (scope) => {
|
|
35
|
+
// In certain situations, the passed context can become undefined.
|
|
36
|
+
// For example, for Astro while prerendering pages at build time.
|
|
37
|
+
// see: https://github.com/getsentry/sentry-javascript/issues/13217
|
|
38
|
+
const context = wrapperOptions.context ;
|
|
39
|
+
|
|
40
|
+
const waitUntil = context?.waitUntil?.bind?.(context);
|
|
41
|
+
|
|
42
|
+
let currentClient = scope.getClient();
|
|
43
|
+
// Check if client exists AND is still usable (transport not disposed)
|
|
44
|
+
// This handles the case where a previous handler disposed the client
|
|
45
|
+
// but the scope still holds a reference to it (e.g., alarm handlers in Durable Objects)
|
|
46
|
+
if (!currentClient?.getTransport()) {
|
|
47
|
+
const client = sdk.init({
|
|
48
|
+
...wrapperOptions.options,
|
|
49
|
+
ctx: context ,
|
|
50
|
+
});
|
|
51
|
+
scope.setClient(client);
|
|
52
|
+
currentClient = client;
|
|
53
|
+
}
|
|
56
54
|
|
|
57
|
-
|
|
55
|
+
const clientToDispose = currentClient;
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
if (!wrapperOptions.spanName) {
|
|
58
|
+
try {
|
|
59
|
+
if (callback) {
|
|
60
|
+
callback(...args);
|
|
61
|
+
}
|
|
62
|
+
const result = Reflect.apply(target, thisArg, args);
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
},
|
|
72
|
-
(e) => {
|
|
73
|
-
core.captureException(e, {
|
|
74
|
-
mechanism: {
|
|
75
|
-
type: 'auto.faas.cloudflare.durable_object',
|
|
76
|
-
handled: false,
|
|
64
|
+
if (core.isThenable(result)) {
|
|
65
|
+
return result.then(
|
|
66
|
+
(res) => {
|
|
67
|
+
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
68
|
+
return res;
|
|
77
69
|
},
|
|
78
|
-
|
|
70
|
+
(e) => {
|
|
71
|
+
core.captureException(e, {
|
|
72
|
+
mechanism: {
|
|
73
|
+
type: 'auto.faas.cloudflare.durable_object',
|
|
74
|
+
handled: false,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
78
|
+
throw e;
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
} else {
|
|
79
82
|
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
95
|
-
throw e;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const attributes = wrapperOptions.spanOp
|
|
100
|
-
? {
|
|
101
|
-
[core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,
|
|
102
|
-
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.durable_object',
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
} catch (e) {
|
|
86
|
+
core.captureException(e, {
|
|
87
|
+
mechanism: {
|
|
88
|
+
type: 'auto.faas.cloudflare.durable_object',
|
|
89
|
+
handled: false,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
93
|
+
throw e;
|
|
94
|
+
}
|
|
103
95
|
}
|
|
104
|
-
: {};
|
|
105
96
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
97
|
+
const attributes = wrapperOptions.spanOp
|
|
98
|
+
? {
|
|
99
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,
|
|
100
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.durable_object',
|
|
101
|
+
}
|
|
102
|
+
: {};
|
|
103
|
+
|
|
104
|
+
return core.startSpan({ name: wrapperOptions.spanName, attributes }, () => {
|
|
105
|
+
try {
|
|
106
|
+
const result = Reflect.apply(target, thisArg, args);
|
|
107
|
+
|
|
108
|
+
if (core.isThenable(result)) {
|
|
109
|
+
return result.then(
|
|
110
|
+
(res) => {
|
|
111
|
+
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
112
|
+
return res;
|
|
121
113
|
},
|
|
122
|
-
|
|
114
|
+
(e) => {
|
|
115
|
+
core.captureException(e, {
|
|
116
|
+
mechanism: {
|
|
117
|
+
type: 'auto.faas.cloudflare.durable_object',
|
|
118
|
+
handled: false,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
122
|
+
throw e;
|
|
123
|
+
},
|
|
124
|
+
);
|
|
125
|
+
} else {
|
|
123
126
|
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
},
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
} catch (e) {
|
|
130
|
+
core.captureException(e, {
|
|
131
|
+
mechanism: {
|
|
132
|
+
type: 'auto.faas.cloudflare.durable_object',
|
|
133
|
+
handled: false,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
waitUntil?.(flush.flushAndDispose(clientToDispose));
|
|
137
|
+
throw e;
|
|
138
|
+
}
|
|
137
139
|
});
|
|
138
|
-
|
|
139
|
-
throw e;
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
};
|
|
140
|
+
};
|
|
143
141
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
return sentryWithScope(wrappedFunction);
|
|
143
|
+
},
|
|
144
|
+
}),
|
|
145
|
+
noMark,
|
|
146
|
+
);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
exports.wrapMethodWithSentry = wrapMethodWithSentry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrapMethodWithSentry.js","sources":["../../src/wrapMethodWithSentry.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport {\n captureException,\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 { CloudflareOptions } from './client';\nimport { flushAndDispose } from './flush';\nimport {
|
|
1
|
+
{"version":3,"file":"wrapMethodWithSentry.js","sources":["../../src/wrapMethodWithSentry.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport {\n captureException,\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 { CloudflareOptions } from './client';\nimport { flushAndDispose } from './flush';\nimport { ensureInstrumented } from './instrument';\nimport { init } from './sdk';\n\n/** Extended DurableObjectState with originalStorage exposed by instrumentContext */\ninterface InstrumentedDurableObjectState extends DurableObjectState {\n originalStorage?: DurableObjectStorage;\n}\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\nexport type UncheckedMethod = (...args: any[]) => any;\ntype OriginalMethod = UncheckedMethod;\n\n/**\n * Wraps a method with Sentry tracing.\n *\n * @param wrapperOptions - The options for the wrapper.\n * @param handler - The method to wrap.\n * @param callback - The callback to call.\n * @param noMark - Whether to mark the method as instrumented.\n * @returns The wrapped method.\n */\nexport function wrapMethodWithSentry<T extends OriginalMethod>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n noMark?: true,\n): T {\n return ensureInstrumented(\n handler,\n original =>\n new Proxy(original, {\n apply(target, thisArg, 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 InstrumentedDurableObjectState | undefined;\n\n const waitUntil = context?.waitUntil?.bind?.(context);\n\n let currentClient = scope.getClient();\n // Check if client exists AND is still usable (transport not disposed)\n // This handles the case where a previous handler disposed the client\n // but the scope still holds a reference to it (e.g., alarm handlers in Durable Objects)\n if (!currentClient?.getTransport()) {\n const client = init({\n ...wrapperOptions.options,\n ctx: context as unknown as ExecutionContext | undefined,\n });\n scope.setClient(client);\n currentClient = client;\n }\n\n const clientToDispose = currentClient;\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?.(flushAndDispose(clientToDispose));\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?.(flushAndDispose(clientToDispose));\n throw e;\n },\n );\n } else {\n waitUntil?.(flushAndDispose(clientToDispose));\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?.(flushAndDispose(clientToDispose));\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?.(flushAndDispose(clientToDispose));\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?.(flushAndDispose(clientToDispose));\n throw e;\n },\n );\n } else {\n waitUntil?.(flushAndDispose(clientToDispose));\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?.(flushAndDispose(clientToDispose));\n throw e;\n }\n });\n };\n\n return sentryWithScope(wrappedFunction);\n },\n }),\n noMark,\n );\n}\n"],"names":["ensureInstrumented","getClient","withScope","withIsolationScope","init","isThenable","flushAndDispose","captureException","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { captureException } from '@sentry/core';
|
|
2
2
|
import { setAsyncLocalStorageAsyncContextStrategy } from './async.js';
|
|
3
|
-
import {
|
|
3
|
+
import { ensureInstrumented, getInstrumented, markAsInstrumented } from './instrument.js';
|
|
4
4
|
import { getFinalOptions } from './options.js';
|
|
5
5
|
import { wrapRequestHandler } from './request.js';
|
|
6
6
|
import { instrumentContext } from './utils/instrumentContext.js';
|
|
@@ -63,16 +63,18 @@ function instrumentDurableObjectWithSentry
|
|
|
63
63
|
|
|
64
64
|
// Any other public methods on the Durable Object instance are RPC calls.
|
|
65
65
|
|
|
66
|
-
if (obj.fetch && typeof obj.fetch === 'function'
|
|
67
|
-
obj.fetch =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
66
|
+
if (obj.fetch && typeof obj.fetch === 'function') {
|
|
67
|
+
obj.fetch = ensureInstrumented(
|
|
68
|
+
obj.fetch,
|
|
69
|
+
original =>
|
|
70
|
+
new Proxy(original, {
|
|
71
|
+
apply(target, thisArg, args) {
|
|
72
|
+
return wrapRequestHandler({ options, request: args[0], context }, () => {
|
|
73
|
+
return Reflect.apply(target, thisArg, args);
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
);
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
if (obj.alarm && typeof obj.alarm === 'function') {
|
|
@@ -173,7 +175,18 @@ function instrumentPrototype(target, methodsToInstrument) {
|
|
|
173
175
|
methodNames.forEach(methodName => {
|
|
174
176
|
const originalMethod = (proto )[methodName];
|
|
175
177
|
|
|
176
|
-
if (!originalMethod
|
|
178
|
+
if (!originalMethod) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const existingInstrumented = getInstrumented(originalMethod);
|
|
183
|
+
if (existingInstrumented) {
|
|
184
|
+
Object.defineProperty(proto, methodName, {
|
|
185
|
+
value: existingInstrumented,
|
|
186
|
+
enumerable: false,
|
|
187
|
+
writable: true,
|
|
188
|
+
configurable: true,
|
|
189
|
+
});
|
|
177
190
|
return;
|
|
178
191
|
}
|
|
179
192
|
|
|
@@ -211,6 +224,11 @@ function instrumentPrototype(target, methodsToInstrument) {
|
|
|
211
224
|
return wrapper.apply(this, args);
|
|
212
225
|
};
|
|
213
226
|
|
|
227
|
+
// Only mark wrappedMethod as instrumented (not originalMethod → wrappedMethod).
|
|
228
|
+
// originalMethod must stay unmapped because wrappedMethod calls
|
|
229
|
+
// wrapMethodWithSentry(options, originalMethod) on each invocation to create
|
|
230
|
+
// a per-instance proxy. If originalMethod mapped to wrappedMethod, that call
|
|
231
|
+
// would return wrappedMethod itself, causing infinite recursion.
|
|
214
232
|
markAsInstrumented(wrappedMethod);
|
|
215
233
|
|
|
216
234
|
// Replace the prototype method
|
|
@@ -1 +1 @@
|
|
|
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":[],"mappings":"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"}
|
|
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 { ensureInstrumented, getInstrumented, 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') {\n obj.fetch = ensureInstrumented(\n obj.fetch,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args) {\n return wrapRequestHandler({ options, request: args[0], context }, () => {\n return Reflect.apply(target, thisArg, args);\n });\n },\n }),\n );\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) {\n return;\n }\n\n const existingInstrumented = getInstrumented(originalMethod);\n if (existingInstrumented) {\n Object.defineProperty(proto, methodName, {\n value: existingInstrumented,\n enumerable: false,\n writable: true,\n configurable: true,\n });\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 // Only mark wrappedMethod as instrumented (not originalMethod → wrappedMethod).\n // originalMethod must stay unmapped because wrappedMethod calls\n // wrapMethodWithSentry(options, originalMethod) on each invocation to create\n // a per-instance proxy. If originalMethod mapped to wrappedMethod, that call\n // would return wrappedMethod itself, causing infinite recursion.\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":[],"mappings":";;;;;;;;AAAA;;AAYA;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,MAAM,wCAAwC,EAAE;AAChD,MAAM,MAAM,OAAA,GAAU,iBAAiB,CAAC,GAAG,CAAC;;AAE5C,MAAM,MAAM,OAAA,GAAU,eAAe,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,KAAA,IAAS,OAAO,GAAG,CAAC,KAAA,KAAU,UAAU,EAAE;AACxD,QAAQ,GAAG,CAAC,KAAA,GAAQ,kBAAkB;AACtC,UAAU,GAAG,CAAC,KAAK;AACnB,UAAU,QAAA;AACV,YAAY,IAAI,KAAK,CAAC,QAAQ,EAAE;AAChC,cAAc,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;AAC3C,gBAAgB,OAAO,kBAAkB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,OAAA,EAAS,EAAE,MAAM;AACxF,kBAAkB,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AAC7D,gBAAgB,CAAC,CAAC;AAClB,cAAc,CAAC;AACf,aAAa,CAAC;AACd,SAAS;AACT,MAAM;;AAEN,MAAM,IAAI,GAAG,CAAC,KAAA,IAAS,OAAO,GAAG,CAAC,KAAA,KAAU,UAAU,EAAE;AACxD,QAAQ,GAAG,CAAC,KAAA,GAAQ,oBAAoB,CAAC,EAAE,OAAO,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,EAAE,OAAO,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,EAAE,OAAO,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,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,kBAAkB;AAC1D,UAAU,GAAG,CAAC,cAAc;AAC5B,UAAU,CAAC,CAAC,EAAE,KAAK;AACnB,YAAY,gBAAgB,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,EAAE,OAAO,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,EAAE,OAAO;AACtB,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,YAAY,EAAE,KAAK;AAC3B,OAAO,CAAC;;AAER,MAAM,IAAI,OAAO,EAAE,0BAA0B,EAAE;AAC/C,QAAQ,mBAAmB,CAAC,MAAM,EAAE,OAAO,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,cAAc,EAAE;AACzB,MAAM;AACN,IAAI;;AAEJ,IAAI,MAAM,oBAAA,GAAuB,eAAe,CAAC,cAAc,CAAC;AAChE,IAAI,IAAI,oBAAoB,EAAE;AAC9B,MAAM,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE;AAC/C,QAAQ,KAAK,EAAE,oBAAoB;AACnC,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,QAAQ,EAAE,IAAI;AACtB,QAAQ,YAAY,EAAE,IAAI;AAC1B,OAAO,CAAC;AACR,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;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAkB,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;;;;"}
|
package/build/esm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, captureCheckIn, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, close, consoleIntegration, consoleLoggingIntegration, continueTrace, createConsolaReporter, createLangChainCallbackHandler, createTransport, dedupeIntegration, eventFiltersIntegration, extraErrorDataIntegration, featureFlagsIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, getTraceData, getTraceMetaTags, growthbookIntegration, inboundFiltersIntegration, instrumentAnthropicAiClient, instrumentGoogleGenAIClient, instrumentLangGraph, instrumentOpenAiClient, instrumentPostgresJsSql, instrumentSupabaseClient, isEnabled, isInitialized, lastEventId, linkedErrorsIntegration, logger, metrics, moduleMetadataIntegration, requestDataIntegration, rewriteFramesIntegration, setContext, setConversationId, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanToBaggageHeader, spanToJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSpan, startSpanManual, supabaseIntegration, suppressTracing, trpcMiddleware, updateSpanName, withActiveSpan, withIsolationScope, withMonitor, withScope, wrapMcpServerWithSentry, zodErrorsIntegration } from '@sentry/core';
|
|
1
|
+
export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, captureCheckIn, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, close, consoleIntegration, consoleLoggingIntegration, continueTrace, createConsolaReporter, createLangChainCallbackHandler, createTransport, dedupeIntegration, eventFiltersIntegration, extraErrorDataIntegration, featureFlagsIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, getTraceData, getTraceMetaTags, growthbookIntegration, inboundFiltersIntegration, instrumentAnthropicAiClient, instrumentGoogleGenAIClient, instrumentLangChainEmbeddings, instrumentLangGraph, instrumentOpenAiClient, instrumentPostgresJsSql, instrumentSupabaseClient, isEnabled, isInitialized, lastEventId, linkedErrorsIntegration, logger, metrics, moduleMetadataIntegration, requestDataIntegration, rewriteFramesIntegration, setContext, setConversationId, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanToBaggageHeader, spanToJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSpan, startSpanManual, supabaseIntegration, suppressTracing, trpcMiddleware, updateSpanName, withActiveSpan, withIsolationScope, withMonitor, withScope, withStreamedSpan, wrapMcpServerWithSentry, zodErrorsIntegration } from '@sentry/core';
|
|
2
2
|
export { withSentry } from './withSentry.js';
|
|
3
3
|
export { instrumentDurableObjectWithSentry } from './durableobject.js';
|
|
4
4
|
export { sentryPagesPlugin } from './pages-plugin.js';
|
package/build/esm/instrument.js
CHANGED
|
@@ -1,24 +1,87 @@
|
|
|
1
|
+
// Use a global WeakMap to track instrumented objects across module instances.
|
|
2
|
+
// This is important for Cloudflare Workers where the module may be bundled
|
|
3
|
+
// separately for workers and Durable Objects, but they share the same global scope.
|
|
4
|
+
// The WeakMap stores original -> instrumented mappings so we can retrieve the
|
|
5
|
+
// instrumented version even if we only have a reference to the original.
|
|
6
|
+
const GLOBAL_KEY = '__SENTRY_INSTRUMENTED_MAP__' ;
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
function getInstrumentedMap() {
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
const globalObj = globalThis ;
|
|
12
|
+
if (!globalObj[GLOBAL_KEY]) {
|
|
13
|
+
globalObj[GLOBAL_KEY] = new WeakMap();
|
|
14
|
+
}
|
|
15
|
+
return globalObj[GLOBAL_KEY];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Check if a value can be used as a WeakMap key.
|
|
20
|
+
* WeakMap keys must be objects or non-registered symbols.
|
|
21
|
+
*/
|
|
22
|
+
function isWeakMapKey(value) {
|
|
23
|
+
return (typeof value === 'object' && value !== null) || typeof value === 'function';
|
|
24
|
+
}
|
|
25
|
+
|
|
1
26
|
/**
|
|
2
|
-
* Mark an object as instrumented.
|
|
27
|
+
* Mark an object as instrumented, storing the instrumented version.
|
|
28
|
+
* @param original The original uninstrumented object
|
|
29
|
+
* @param instrumented The instrumented version (defaults to original if not provided)
|
|
3
30
|
*/
|
|
4
|
-
function markAsInstrumented(
|
|
31
|
+
function markAsInstrumented(original, instrumented) {
|
|
5
32
|
try {
|
|
6
|
-
(
|
|
33
|
+
if (isWeakMapKey(original)) {
|
|
34
|
+
// Store mapping from original to instrumented version
|
|
35
|
+
// If instrumented is not provided, store original (for backwards compat)
|
|
36
|
+
getInstrumentedMap().set(original, instrumented ?? original);
|
|
37
|
+
}
|
|
38
|
+
// Also mark the instrumented version itself so we recognize it
|
|
39
|
+
if (isWeakMapKey(instrumented) && instrumented !== original) {
|
|
40
|
+
getInstrumentedMap().set(instrumented, instrumented);
|
|
41
|
+
}
|
|
7
42
|
} catch {
|
|
8
43
|
// ignore errors here
|
|
9
44
|
}
|
|
10
45
|
}
|
|
11
46
|
|
|
12
47
|
/**
|
|
13
|
-
*
|
|
48
|
+
* Get the instrumented version of an object, if available.
|
|
49
|
+
* Returns the instrumented version if the object was previously instrumented,
|
|
50
|
+
* or undefined if not found.
|
|
14
51
|
*/
|
|
15
|
-
function
|
|
52
|
+
function getInstrumented(obj) {
|
|
16
53
|
try {
|
|
17
|
-
|
|
54
|
+
if (isWeakMapKey(obj)) {
|
|
55
|
+
return getInstrumentedMap().get(obj) ;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return undefined;
|
|
18
59
|
} catch {
|
|
19
|
-
return
|
|
60
|
+
return undefined;
|
|
20
61
|
}
|
|
21
62
|
}
|
|
22
63
|
|
|
23
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Returns the already-instrumented version of `original` if one exists,
|
|
66
|
+
* otherwise calls `instrumentFn` to create it, marks the mapping, and returns it.
|
|
67
|
+
*
|
|
68
|
+
* @param noMark - If true, skips storing the original→instrumented mapping.
|
|
69
|
+
*/
|
|
70
|
+
function ensureInstrumented(original, instrumentFn, noMark) {
|
|
71
|
+
const existing = getInstrumented(original);
|
|
72
|
+
|
|
73
|
+
if (existing) {
|
|
74
|
+
return existing;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const instrumented = instrumentFn(original);
|
|
78
|
+
|
|
79
|
+
if (!noMark) {
|
|
80
|
+
markAsInstrumented(original, instrumented);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return instrumented;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { ensureInstrumented, getInstrumented, markAsInstrumented };
|
|
24
87
|
//# sourceMappingURL=instrument.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument.js","sources":["../../src/instrument.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"instrument.js","sources":["../../src/instrument.ts"],"sourcesContent":["// Use a global WeakMap to track instrumented objects across module instances.\n// This is important for Cloudflare Workers where the module may be bundled\n// separately for workers and Durable Objects, but they share the same global scope.\n// The WeakMap stores original -> instrumented mappings so we can retrieve the\n// instrumented version even if we only have a reference to the original.\nconst GLOBAL_KEY = '__SENTRY_INSTRUMENTED_MAP__' as const;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getInstrumentedMap(): WeakMap<any, any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const globalObj = globalThis as typeof globalThis & { [GLOBAL_KEY]?: WeakMap<any, any> };\n if (!globalObj[GLOBAL_KEY]) {\n globalObj[GLOBAL_KEY] = new WeakMap();\n }\n return globalObj[GLOBAL_KEY];\n}\n\n/**\n * Check if a value can be used as a WeakMap key.\n * WeakMap keys must be objects or non-registered symbols.\n */\nfunction isWeakMapKey(value: unknown): value is object {\n return (typeof value === 'object' && value !== null) || typeof value === 'function';\n}\n\n/**\n * Mark an object as instrumented, storing the instrumented version.\n * @param original The original uninstrumented object\n * @param instrumented The instrumented version (defaults to original if not provided)\n */\nexport function markAsInstrumented<T>(original: T, instrumented?: T): void {\n try {\n if (isWeakMapKey(original)) {\n // Store mapping from original to instrumented version\n // If instrumented is not provided, store original (for backwards compat)\n getInstrumentedMap().set(original, instrumented ?? original);\n }\n // Also mark the instrumented version itself so we recognize it\n if (isWeakMapKey(instrumented) && instrumented !== original) {\n getInstrumentedMap().set(instrumented, instrumented);\n }\n } catch {\n // ignore errors here\n }\n}\n\n/**\n * Get the instrumented version of an object, if available.\n * Returns the instrumented version if the object was previously instrumented,\n * or undefined if not found.\n */\nexport function getInstrumented<T>(obj: T): T | undefined {\n try {\n if (isWeakMapKey(obj)) {\n return getInstrumentedMap().get(obj) as T | undefined;\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Returns the already-instrumented version of `original` if one exists,\n * otherwise calls `instrumentFn` to create it, marks the mapping, and returns it.\n *\n * @param noMark - If true, skips storing the original→instrumented mapping.\n */\nexport function ensureInstrumented<T>(original: T, instrumentFn: (original: T) => T, noMark?: boolean): T {\n const existing = getInstrumented(original);\n\n if (existing) {\n return existing;\n }\n\n const instrumented = instrumentFn(original);\n\n if (!noMark) {\n markAsInstrumented(original, instrumented);\n }\n\n return instrumented;\n}\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA,MAAM,UAAA,GAAa,6BAAA;;AAEnB;AACA,SAAS,kBAAkB,GAAsB;AACjD;AACA,EAAE,MAAM,SAAA,GAAY,UAAA;AACpB,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE;AAC9B,IAAI,SAAS,CAAC,UAAU,CAAA,GAAI,IAAI,OAAO,EAAE;AACzC,EAAE;AACF,EAAE,OAAO,SAAS,CAAC,UAAU,CAAC;AAC9B;;AAEA;AACA;AACA;AACA;AACA,SAAS,YAAY,CAAC,KAAK,EAA4B;AACvD,EAAE,OAAO,CAAC,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAI,KAAK,OAAO,KAAA,KAAU,UAAU;AACrF;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,kBAAkB,CAAI,QAAQ,EAAK,YAAY,EAAY;AAC3E,EAAE,IAAI;AACN,IAAI,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE;AAChC;AACA;AACA,MAAM,kBAAkB,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAA,IAAgB,QAAQ,CAAC;AAClE,IAAI;AACJ;AACA,IAAI,IAAI,YAAY,CAAC,YAAY,KAAK,YAAA,KAAiB,QAAQ,EAAE;AACjE,MAAM,kBAAkB,EAAE,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC;AAC1D,IAAI;AACJ,EAAE,EAAE,MAAM;AACV;AACA,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAI,GAAG,EAAoB;AAC1D,EAAE,IAAI;AACN,IAAI,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE;AAC3B,MAAM,OAAO,kBAAkB,EAAE,CAAC,GAAG,CAAC,GAAG,CAAA;AACzC,IAAI;;AAEJ,IAAI,OAAO,SAAS;AACpB,EAAE,EAAE,MAAM;AACV,IAAI,OAAO,SAAS;AACpB,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,kBAAkB,CAAI,QAAQ,EAAK,YAAY,EAAsB,MAAM,EAAe;AAC1G,EAAE,MAAM,QAAA,GAAW,eAAe,CAAC,QAAQ,CAAC;;AAE5C,EAAE,IAAI,QAAQ,EAAE;AAChB,IAAI,OAAO,QAAQ;AACnB,EAAE;;AAEF,EAAE,MAAM,YAAA,GAAe,YAAY,CAAC,QAAQ,CAAC;;AAE7C,EAAE,IAAI,CAAC,MAAM,EAAE;AACf,IAAI,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC;AAC9C,EAAE;;AAEF,EAAE,OAAO,YAAY;AACrB;;;;"}
|