@sentry/cloudflare 10.53.1 → 10.55.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/async.js +4 -30
- package/build/cjs/async.js.map +1 -1
- package/build/cjs/client.js +31 -58
- package/build/cjs/client.js.map +1 -1
- package/build/cjs/d1.js +26 -80
- package/build/cjs/d1.js.map +1 -1
- package/build/cjs/debug-build.js +0 -5
- package/build/cjs/debug-build.js.map +1 -1
- package/build/cjs/durableobject.js +44 -131
- package/build/cjs/durableobject.js.map +1 -1
- package/build/cjs/flush.js +53 -34
- package/build/cjs/flush.js.map +1 -1
- package/build/cjs/instrument.js +7 -48
- package/build/cjs/instrument.js.map +1 -1
- package/build/cjs/instrumentations/instrumentDurableObjectNamespace.js +9 -34
- package/build/cjs/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/cjs/instrumentations/instrumentDurableObjectStorage.js +20 -54
- package/build/cjs/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
- package/build/cjs/instrumentations/instrumentWorkerEntrypoint.js +12 -66
- package/build/cjs/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentEmail.js +21 -43
- package/build/cjs/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentEnv.js +12 -42
- package/build/cjs/instrumentations/worker/instrumentEnv.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentFetch.js +20 -34
- package/build/cjs/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentFetcher.js +5 -19
- package/build/cjs/instrumentations/worker/instrumentFetcher.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentQueue.js +30 -62
- package/build/cjs/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentQueueProducer.js +31 -57
- package/build/cjs/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentScheduled.js +25 -54
- package/build/cjs/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentTail.js +16 -43
- package/build/cjs/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/cjs/integrations/fetch.js +24 -56
- package/build/cjs/integrations/fetch.js.map +1 -1
- package/build/cjs/integrations/hono.js +7 -38
- package/build/cjs/integrations/hono.js.map +1 -1
- package/build/cjs/integrations/httpServer.js +6 -39
- package/build/cjs/integrations/httpServer.js.map +1 -1
- package/build/cjs/integrations/tracing/vercelai.js +3 -31
- package/build/cjs/integrations/tracing/vercelai.js.map +1 -1
- package/build/cjs/opentelemetry/tracer.js +17 -45
- package/build/cjs/opentelemetry/tracer.js.map +1 -1
- package/build/cjs/options.js +10 -46
- package/build/cjs/options.js.map +1 -1
- package/build/cjs/pages-plugin.js +9 -42
- package/build/cjs/pages-plugin.js.map +1 -1
- package/build/cjs/request.js +22 -68
- package/build/cjs/request.js.map +1 -1
- package/build/cjs/scope-utils.js +4 -15
- package/build/cjs/scope-utils.js.map +1 -1
- package/build/cjs/sdk.js +8 -25
- package/build/cjs/sdk.js.map +1 -1
- package/build/cjs/transport.js +14 -48
- package/build/cjs/transport.js.map +1 -1
- package/build/cjs/utils/instrumentContext.js +16 -52
- package/build/cjs/utils/instrumentContext.js.map +1 -1
- package/build/cjs/utils/isBinding.js +3 -23
- package/build/cjs/utils/isBinding.js.map +1 -1
- package/build/cjs/utils/isCloudflareClass.js +2 -8
- package/build/cjs/utils/isCloudflareClass.js.map +1 -1
- package/build/cjs/utils/rpcMeta.js +8 -32
- package/build/cjs/utils/rpcMeta.js.map +1 -1
- package/build/cjs/utils/rpcOptions.js +9 -32
- package/build/cjs/utils/rpcOptions.js.map +1 -1
- package/build/cjs/utils/streaming.js +3 -29
- package/build/cjs/utils/streaming.js.map +1 -1
- package/build/cjs/utils/traceLinks.js +8 -33
- package/build/cjs/utils/traceLinks.js.map +1 -1
- package/build/cjs/vendor/stacktrace.js +6 -27
- package/build/cjs/vendor/stacktrace.js.map +1 -1
- package/build/cjs/withSentry.js +16 -47
- package/build/cjs/withSentry.js.map +1 -1
- package/build/cjs/workflows.js +40 -100
- package/build/cjs/workflows.js.map +1 -1
- package/build/cjs/wrapMethodWithSentry.js +110 -167
- package/build/cjs/wrapMethodWithSentry.js.map +1 -1
- package/build/esm/async.js +4 -30
- package/build/esm/async.js.map +1 -1
- package/build/esm/client.js +31 -58
- package/build/esm/client.js.map +1 -1
- package/build/esm/d1.js +26 -80
- package/build/esm/d1.js.map +1 -1
- package/build/esm/debug-build.js +0 -5
- package/build/esm/debug-build.js.map +1 -1
- package/build/esm/durableobject.js +44 -131
- package/build/esm/durableobject.js.map +1 -1
- package/build/esm/flush.js +53 -35
- package/build/esm/flush.js.map +1 -1
- package/build/esm/instrument.js +7 -48
- package/build/esm/instrument.js.map +1 -1
- package/build/esm/instrumentations/instrumentDurableObjectNamespace.js +9 -34
- package/build/esm/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/esm/instrumentations/instrumentDurableObjectStorage.js +20 -54
- package/build/esm/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
- package/build/esm/instrumentations/instrumentWorkerEntrypoint.js +12 -66
- package/build/esm/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentEmail.js +21 -43
- package/build/esm/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentEnv.js +12 -42
- package/build/esm/instrumentations/worker/instrumentEnv.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentFetch.js +20 -34
- package/build/esm/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentFetcher.js +5 -19
- package/build/esm/instrumentations/worker/instrumentFetcher.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentQueue.js +30 -62
- package/build/esm/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentQueueProducer.js +31 -57
- package/build/esm/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentScheduled.js +25 -54
- package/build/esm/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentTail.js +16 -43
- package/build/esm/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/esm/integrations/fetch.js +24 -56
- package/build/esm/integrations/fetch.js.map +1 -1
- package/build/esm/integrations/hono.js +7 -38
- package/build/esm/integrations/hono.js.map +1 -1
- package/build/esm/integrations/httpServer.js +6 -39
- package/build/esm/integrations/httpServer.js.map +1 -1
- package/build/esm/integrations/tracing/vercelai.js +3 -31
- package/build/esm/integrations/tracing/vercelai.js.map +1 -1
- package/build/esm/opentelemetry/tracer.js +17 -45
- package/build/esm/opentelemetry/tracer.js.map +1 -1
- package/build/esm/options.js +10 -46
- package/build/esm/options.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/pages-plugin.js +9 -42
- package/build/esm/pages-plugin.js.map +1 -1
- package/build/esm/request.js +23 -69
- package/build/esm/request.js.map +1 -1
- package/build/esm/scope-utils.js +4 -15
- package/build/esm/scope-utils.js.map +1 -1
- package/build/esm/sdk.js +8 -25
- package/build/esm/sdk.js.map +1 -1
- package/build/esm/transport.js +14 -48
- package/build/esm/transport.js.map +1 -1
- package/build/esm/utils/instrumentContext.js +16 -52
- package/build/esm/utils/instrumentContext.js.map +1 -1
- package/build/esm/utils/isBinding.js +3 -23
- package/build/esm/utils/isBinding.js.map +1 -1
- package/build/esm/utils/isCloudflareClass.js +2 -8
- package/build/esm/utils/isCloudflareClass.js.map +1 -1
- package/build/esm/utils/rpcMeta.js +8 -32
- package/build/esm/utils/rpcMeta.js.map +1 -1
- package/build/esm/utils/rpcOptions.js +9 -32
- package/build/esm/utils/rpcOptions.js.map +1 -1
- package/build/esm/utils/streaming.js +3 -29
- package/build/esm/utils/streaming.js.map +1 -1
- package/build/esm/utils/traceLinks.js +8 -33
- package/build/esm/utils/traceLinks.js.map +1 -1
- package/build/esm/vendor/stacktrace.js +6 -27
- package/build/esm/vendor/stacktrace.js.map +1 -1
- package/build/esm/withSentry.js +16 -47
- package/build/esm/withSentry.js.map +1 -1
- package/build/esm/workflows.js +40 -100
- package/build/esm/workflows.js.map +1 -1
- package/build/esm/wrapMethodWithSentry.js +110 -167
- package/build/esm/wrapMethodWithSentry.js.map +1 -1
- package/build/types/client.d.ts.map +1 -1
- package/build/types/flush.d.ts +15 -0
- package/build/types/flush.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentFetch.d.ts.map +1 -1
- package/build/types/integrations/hono.d.ts +3 -0
- package/build/types/integrations/hono.d.ts.map +1 -1
- package/build/types/pages-plugin.d.ts.map +1 -1
- package/build/types/request.d.ts.map +1 -1
- package/build/types-ts3.8/flush.d.ts +15 -0
- package/build/types-ts3.8/integrations/hono.d.ts +3 -0
- package/package.json +2 -2
|
@@ -7,89 +7,102 @@ const sdk = require('./sdk.js');
|
|
|
7
7
|
const rpcMeta = require('./utils/rpcMeta.js');
|
|
8
8
|
const traceLinks = require('./utils/traceLinks.js');
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Wraps a method with Sentry error tracking and optional tracing.
|
|
14
|
-
* Supports starting new traces and linking to previous invocations via Durable Object storage.
|
|
15
|
-
*
|
|
16
|
-
* @param wrapperOptions - The options for the wrapper.
|
|
17
|
-
* @param handler - The method to wrap.
|
|
18
|
-
* @param callback - The callback to call.
|
|
19
|
-
* @param noMark - Whether to mark the method as instrumented.
|
|
20
|
-
* @returns The wrapped method.
|
|
21
|
-
*/
|
|
22
|
-
function wrapMethodWithSentry(
|
|
23
|
-
wrapperOptions,
|
|
24
|
-
handler,
|
|
25
|
-
callback,
|
|
26
|
-
noMark,
|
|
27
|
-
) {
|
|
10
|
+
function wrapMethodWithSentry(wrapperOptions, handler, callback, noMark) {
|
|
28
11
|
return instrument.ensureInstrumented(
|
|
29
12
|
handler,
|
|
30
|
-
original =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
13
|
+
(original) => new Proxy(original, {
|
|
14
|
+
apply(target, thisArg, rawArgs) {
|
|
15
|
+
const { startNewTrace } = wrapperOptions;
|
|
16
|
+
let args = rawArgs;
|
|
17
|
+
let rpcMeta$1;
|
|
18
|
+
if (wrapperOptions.spanOp === "rpc") {
|
|
19
|
+
const extracted = rpcMeta.extractRpcMeta(rawArgs);
|
|
20
|
+
args = extracted.args;
|
|
21
|
+
rpcMeta$1 = extracted.rpcMeta;
|
|
22
|
+
}
|
|
23
|
+
const currentClient = core.getClient();
|
|
24
|
+
const sentryWithScope = startNewTrace ? core.withIsolationScope : currentClient ? core.withScope : core.withIsolationScope;
|
|
25
|
+
const wrappedFunction = (scope) => {
|
|
26
|
+
const context = wrapperOptions.context;
|
|
27
|
+
const waitUntil = context?.waitUntil?.bind?.(context);
|
|
28
|
+
const storage = context && "originalStorage" in context ? context.originalStorage : void 0;
|
|
29
|
+
let scopeClient = scope.getClient();
|
|
30
|
+
if (startNewTrace || !scopeClient?.getTransport()) {
|
|
31
|
+
const client = sdk.init({
|
|
32
|
+
...wrapperOptions.options,
|
|
33
|
+
ctx: context
|
|
34
|
+
});
|
|
35
|
+
scope.setClient(client);
|
|
36
|
+
scopeClient = client;
|
|
45
37
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
38
|
+
const clientToDispose = scopeClient;
|
|
39
|
+
const methodName = wrapperOptions.spanName || "unknown";
|
|
40
|
+
const teardown = async () => {
|
|
41
|
+
if (startNewTrace && storage) {
|
|
42
|
+
await traceLinks.storeSpanContext(storage, methodName);
|
|
43
|
+
}
|
|
44
|
+
await flush.flushAndDispose(clientToDispose);
|
|
45
|
+
};
|
|
46
|
+
if (!wrapperOptions.spanName) {
|
|
47
|
+
try {
|
|
48
|
+
if (callback) {
|
|
49
|
+
callback(...args);
|
|
50
|
+
}
|
|
51
|
+
const result = Reflect.apply(target, thisArg, args);
|
|
52
|
+
if (core.isThenable(result)) {
|
|
53
|
+
return result.then(
|
|
54
|
+
(res) => {
|
|
55
|
+
waitUntil?.(teardown());
|
|
56
|
+
return res;
|
|
57
|
+
},
|
|
58
|
+
(e) => {
|
|
59
|
+
core.captureException(e, {
|
|
60
|
+
mechanism: {
|
|
61
|
+
type: "auto.faas.cloudflare.durable_object",
|
|
62
|
+
handled: false
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
waitUntil?.(teardown());
|
|
66
|
+
throw e;
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
} else {
|
|
70
|
+
waitUntil?.(teardown());
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
} catch (e) {
|
|
74
|
+
core.captureException(e, {
|
|
75
|
+
mechanism: {
|
|
76
|
+
type: "auto.faas.cloudflare.durable_object",
|
|
77
|
+
handled: false
|
|
78
|
+
}
|
|
70
79
|
});
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
waitUntil?.(teardown());
|
|
81
|
+
throw e;
|
|
73
82
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
}
|
|
84
|
+
const attributes = wrapperOptions.spanOp ? {
|
|
85
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,
|
|
86
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.faas.cloudflare.durable_object"
|
|
87
|
+
} : {};
|
|
88
|
+
const executeSpan = () => {
|
|
89
|
+
return core.startSpan({ name: methodName, attributes }, (span) => {
|
|
79
90
|
if (startNewTrace && storage) {
|
|
80
|
-
|
|
91
|
+
waitUntil?.(
|
|
92
|
+
traceLinks.getStoredSpanContext(storage, methodName).then((storedContext) => {
|
|
93
|
+
if (storedContext) {
|
|
94
|
+
span.addLinks(traceLinks.buildSpanLinks(storedContext));
|
|
95
|
+
const sampledFlag = storedContext.sampled ? "1" : "0";
|
|
96
|
+
span.setAttribute(
|
|
97
|
+
"sentry.previous_trace",
|
|
98
|
+
`${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
);
|
|
81
103
|
}
|
|
82
|
-
await flush.flushAndDispose(clientToDispose);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
if (!wrapperOptions.spanName) {
|
|
86
104
|
try {
|
|
87
|
-
if (callback) {
|
|
88
|
-
callback(...args);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
105
|
const result = Reflect.apply(target, thisArg, args);
|
|
92
|
-
|
|
93
106
|
if (core.isThenable(result)) {
|
|
94
107
|
return result.then(
|
|
95
108
|
(res) => {
|
|
@@ -99,13 +112,13 @@ function wrapMethodWithSentry(
|
|
|
99
112
|
(e) => {
|
|
100
113
|
core.captureException(e, {
|
|
101
114
|
mechanism: {
|
|
102
|
-
type:
|
|
103
|
-
handled: false
|
|
104
|
-
}
|
|
115
|
+
type: "auto.faas.cloudflare.durable_object",
|
|
116
|
+
handled: false
|
|
117
|
+
}
|
|
105
118
|
});
|
|
106
119
|
waitUntil?.(teardown());
|
|
107
120
|
throw e;
|
|
108
|
-
}
|
|
121
|
+
}
|
|
109
122
|
);
|
|
110
123
|
} else {
|
|
111
124
|
waitUntil?.(teardown());
|
|
@@ -114,100 +127,30 @@ function wrapMethodWithSentry(
|
|
|
114
127
|
} catch (e) {
|
|
115
128
|
core.captureException(e, {
|
|
116
129
|
mechanism: {
|
|
117
|
-
type:
|
|
118
|
-
handled: false
|
|
119
|
-
}
|
|
130
|
+
type: "auto.faas.cloudflare.durable_object",
|
|
131
|
+
handled: false
|
|
132
|
+
}
|
|
120
133
|
});
|
|
121
134
|
waitUntil?.(teardown());
|
|
122
135
|
throw e;
|
|
123
136
|
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const attributes = wrapperOptions.spanOp
|
|
127
|
-
? {
|
|
128
|
-
[core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,
|
|
129
|
-
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.durable_object',
|
|
130
|
-
}
|
|
131
|
-
: {};
|
|
132
|
-
|
|
133
|
-
const executeSpan = () => {
|
|
134
|
-
return core.startSpan({ name: methodName, attributes }, span => {
|
|
135
|
-
// When linking to previous trace, fetch the stored context and add links asynchronously
|
|
136
|
-
// This avoids blocking the response while fetching from storage
|
|
137
|
-
if (startNewTrace && storage) {
|
|
138
|
-
waitUntil?.(
|
|
139
|
-
traceLinks.getStoredSpanContext(storage, methodName).then(storedContext => {
|
|
140
|
-
if (storedContext) {
|
|
141
|
-
span.addLinks(traceLinks.buildSpanLinks(storedContext));
|
|
142
|
-
// TODO: Remove this once EAP can store span links. We currently only set this attribute so that we
|
|
143
|
-
// can obtain the previous trace information from the EAP store. Long-term, EAP will handle
|
|
144
|
-
// span links and then we should remove this again. Also throwing in a TODO(v11), to remind us
|
|
145
|
-
// to check this at v11 time :)
|
|
146
|
-
const sampledFlag = storedContext.sampled ? '1' : '0';
|
|
147
|
-
span.setAttribute(
|
|
148
|
-
'sentry.previous_trace',
|
|
149
|
-
`${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}`,
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
}),
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
const result = Reflect.apply(target, thisArg, args);
|
|
158
|
-
|
|
159
|
-
if (core.isThenable(result)) {
|
|
160
|
-
return result.then(
|
|
161
|
-
(res) => {
|
|
162
|
-
waitUntil?.(teardown());
|
|
163
|
-
return res;
|
|
164
|
-
},
|
|
165
|
-
(e) => {
|
|
166
|
-
core.captureException(e, {
|
|
167
|
-
mechanism: {
|
|
168
|
-
type: 'auto.faas.cloudflare.durable_object',
|
|
169
|
-
handled: false,
|
|
170
|
-
},
|
|
171
|
-
});
|
|
172
|
-
waitUntil?.(teardown());
|
|
173
|
-
throw e;
|
|
174
|
-
},
|
|
175
|
-
);
|
|
176
|
-
} else {
|
|
177
|
-
waitUntil?.(teardown());
|
|
178
|
-
return result;
|
|
179
|
-
}
|
|
180
|
-
} catch (e) {
|
|
181
|
-
core.captureException(e, {
|
|
182
|
-
mechanism: {
|
|
183
|
-
type: 'auto.faas.cloudflare.durable_object',
|
|
184
|
-
handled: false,
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
waitUntil?.(teardown());
|
|
188
|
-
throw e;
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
if (rpcMeta$1) {
|
|
194
|
-
return core.continueTrace(
|
|
195
|
-
{ sentryTrace: rpcMeta$1['sentry-trace'] || '', baggage: rpcMeta$1.baggage || '' },
|
|
196
|
-
executeSpan,
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (startNewTrace) {
|
|
201
|
-
return core.startNewTrace(() => executeSpan());
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return executeSpan();
|
|
137
|
+
});
|
|
205
138
|
};
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
139
|
+
if (rpcMeta$1) {
|
|
140
|
+
return core.continueTrace(
|
|
141
|
+
{ sentryTrace: rpcMeta$1["sentry-trace"] || "", baggage: rpcMeta$1.baggage || "" },
|
|
142
|
+
executeSpan
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (startNewTrace) {
|
|
146
|
+
return core.startNewTrace(() => executeSpan());
|
|
147
|
+
}
|
|
148
|
+
return executeSpan();
|
|
149
|
+
};
|
|
150
|
+
return sentryWithScope(wrappedFunction);
|
|
151
|
+
}
|
|
152
|
+
}),
|
|
153
|
+
noMark
|
|
211
154
|
);
|
|
212
155
|
}
|
|
213
156
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrapMethodWithSentry.js","sources":["../../src/wrapMethodWithSentry.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport type { SerializedTraceData } from '@sentry/core';\nimport {\n captureException,\n continueTrace,\n getClient,\n isThenable,\n type Scope,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startNewTrace as startNewTraceCore,\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';\nimport { extractRpcMeta } from './utils/rpcMeta';\nimport { buildSpanLinks, getStoredSpanContext, storeSpanContext } from './utils/traceLinks';\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 | InstrumentedDurableObjectState;\n /**\n * If true, starts a fresh trace instead of inheriting from a parent trace.\n * Useful for scheduled/independent invocations like alarms.\n *\n * If true, it also stores the current span context and links to the previous invocation's span.\n * Uses Durable Object storage to persist the link. The link is set asynchronously via `span.addLinks()`\n * in a `waitUntil` to avoid blocking.\n *\n * @default false\n */\n startNewTrace?: boolean;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type UncheckedMethod = (...args: any[]) => any;\ntype OriginalMethod = UncheckedMethod;\n\n/**\n * Wraps a method with Sentry error tracking and optional tracing.\n * Supports starting new traces and linking to previous invocations via Durable Object storage.\n *\n * @param wrapperOptions - The options for the wrapper.\n * @param handler - The method to wrap.\n * @param callback - The callback to call.\n * @param noMark - Whether to mark the method as instrumented.\n * @returns The wrapped method.\n */\nexport function wrapMethodWithSentry<T extends OriginalMethod>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n noMark?: true,\n): T {\n return ensureInstrumented(\n handler,\n original =>\n new Proxy(original, {\n apply(target, thisArg, rawArgs: Parameters<T>) {\n const { startNewTrace } = wrapperOptions;\n\n // For RPC methods, extract Sentry trace context from the trailing argument.\n // The caller side (instrumentDurableObjectStub / JSRPC proxy) appends it;\n // we strip it here so the user's method never sees it.\n let args = rawArgs;\n let rpcMeta: SerializedTraceData | undefined;\n\n if (wrapperOptions.spanOp === 'rpc') {\n const extracted = extractRpcMeta(rawArgs);\n args = extracted.args;\n rpcMeta = extracted.rpcMeta;\n }\n\n // For startNewTrace, always use withIsolationScope to ensure a fresh scope\n // Otherwise, use existing client's scope or isolation scope\n const currentClient = getClient();\n const sentryWithScope = startNewTrace ? withIsolationScope : currentClient ? withScope : withIsolationScope;\n\n const wrappedFunction = (scope: Scope): unknown | Promise<unknown> => {\n // In certain situations, the passed context can become undefined.\n // For example, for Astro while prerendering pages at build time.\n // see: https://github.com/getsentry/sentry-javascript/issues/13217\n const context: typeof wrapperOptions.context | undefined = wrapperOptions.context;\n\n const waitUntil = context?.waitUntil?.bind?.(context);\n const storage = context && 'originalStorage' in context ? context.originalStorage : undefined;\n\n let scopeClient = 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 // For startNewTrace, always create a fresh client\n if (startNewTrace || !scopeClient?.getTransport()) {\n const client = init({\n ...wrapperOptions.options,\n ctx: context as unknown as ExecutionContext | undefined,\n });\n scope.setClient(client);\n scopeClient = client;\n }\n\n const clientToDispose = scopeClient;\n const methodName = wrapperOptions.spanName || 'unknown';\n\n const teardown = async (): Promise<void> => {\n if (startNewTrace && storage) {\n await storeSpanContext(storage, methodName);\n }\n await flushAndDispose(clientToDispose);\n };\n\n if (!wrapperOptions.spanName) {\n try {\n if (callback) {\n callback(...args);\n }\n\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(\n (res: unknown) => {\n waitUntil?.(teardown());\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?.(teardown());\n throw e;\n },\n );\n } else {\n waitUntil?.(teardown());\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?.(teardown());\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 const executeSpan = (): unknown => {\n return startSpan({ name: methodName, attributes }, span => {\n // When linking to previous trace, fetch the stored context and add links asynchronously\n // This avoids blocking the response while fetching from storage\n if (startNewTrace && storage) {\n waitUntil?.(\n getStoredSpanContext(storage, methodName).then(storedContext => {\n if (storedContext) {\n span.addLinks(buildSpanLinks(storedContext));\n // TODO: Remove this once EAP can store span links. We currently only set this attribute so that we\n // can obtain the previous trace information from the EAP store. Long-term, EAP will handle\n // span links and then we should remove this again. Also throwing in a TODO(v11), to remind us\n // to check this at v11 time :)\n const sampledFlag = storedContext.sampled ? '1' : '0';\n span.setAttribute(\n 'sentry.previous_trace',\n `${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}`,\n );\n }\n }),\n );\n }\n\n try {\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(\n (res: unknown) => {\n waitUntil?.(teardown());\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?.(teardown());\n throw e;\n },\n );\n } else {\n waitUntil?.(teardown());\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?.(teardown());\n throw e;\n }\n });\n };\n\n if (rpcMeta) {\n return continueTrace(\n { sentryTrace: rpcMeta['sentry-trace'] || '', baggage: rpcMeta.baggage || '' },\n executeSpan,\n );\n }\n\n if (startNewTrace) {\n return startNewTraceCore(() => executeSpan());\n }\n\n return executeSpan();\n };\n\n return sentryWithScope(wrappedFunction);\n },\n }),\n noMark,\n );\n}\n"],"names":["ensureInstrumented","rpcMeta","extractRpcMeta","getClient","withIsolationScope","withScope","init","storeSpanContext","flushAndDispose","isThenable","captureException","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","getStoredSpanContext","buildSpanLinks","continueTrace","startNewTraceCore"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wrapMethodWithSentry.js","sources":["../../src/wrapMethodWithSentry.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport type { SerializedTraceData } from '@sentry/core';\nimport {\n captureException,\n continueTrace,\n getClient,\n isThenable,\n type Scope,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startNewTrace as startNewTraceCore,\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';\nimport { extractRpcMeta } from './utils/rpcMeta';\nimport { buildSpanLinks, getStoredSpanContext, storeSpanContext } from './utils/traceLinks';\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 | InstrumentedDurableObjectState;\n /**\n * If true, starts a fresh trace instead of inheriting from a parent trace.\n * Useful for scheduled/independent invocations like alarms.\n *\n * If true, it also stores the current span context and links to the previous invocation's span.\n * Uses Durable Object storage to persist the link. The link is set asynchronously via `span.addLinks()`\n * in a `waitUntil` to avoid blocking.\n *\n * @default false\n */\n startNewTrace?: boolean;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type UncheckedMethod = (...args: any[]) => any;\ntype OriginalMethod = UncheckedMethod;\n\n/**\n * Wraps a method with Sentry error tracking and optional tracing.\n * Supports starting new traces and linking to previous invocations via Durable Object storage.\n *\n * @param wrapperOptions - The options for the wrapper.\n * @param handler - The method to wrap.\n * @param callback - The callback to call.\n * @param noMark - Whether to mark the method as instrumented.\n * @returns The wrapped method.\n */\nexport function wrapMethodWithSentry<T extends OriginalMethod>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n noMark?: true,\n): T {\n return ensureInstrumented(\n handler,\n original =>\n new Proxy(original, {\n apply(target, thisArg, rawArgs: Parameters<T>) {\n const { startNewTrace } = wrapperOptions;\n\n // For RPC methods, extract Sentry trace context from the trailing argument.\n // The caller side (instrumentDurableObjectStub / JSRPC proxy) appends it;\n // we strip it here so the user's method never sees it.\n let args = rawArgs;\n let rpcMeta: SerializedTraceData | undefined;\n\n if (wrapperOptions.spanOp === 'rpc') {\n const extracted = extractRpcMeta(rawArgs);\n args = extracted.args;\n rpcMeta = extracted.rpcMeta;\n }\n\n // For startNewTrace, always use withIsolationScope to ensure a fresh scope\n // Otherwise, use existing client's scope or isolation scope\n const currentClient = getClient();\n const sentryWithScope = startNewTrace ? withIsolationScope : currentClient ? withScope : withIsolationScope;\n\n const wrappedFunction = (scope: Scope): unknown | Promise<unknown> => {\n // In certain situations, the passed context can become undefined.\n // For example, for Astro while prerendering pages at build time.\n // see: https://github.com/getsentry/sentry-javascript/issues/13217\n const context: typeof wrapperOptions.context | undefined = wrapperOptions.context;\n\n const waitUntil = context?.waitUntil?.bind?.(context);\n const storage = context && 'originalStorage' in context ? context.originalStorage : undefined;\n\n let scopeClient = 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 // For startNewTrace, always create a fresh client\n if (startNewTrace || !scopeClient?.getTransport()) {\n const client = init({\n ...wrapperOptions.options,\n ctx: context as unknown as ExecutionContext | undefined,\n });\n scope.setClient(client);\n scopeClient = client;\n }\n\n const clientToDispose = scopeClient;\n const methodName = wrapperOptions.spanName || 'unknown';\n\n const teardown = async (): Promise<void> => {\n if (startNewTrace && storage) {\n await storeSpanContext(storage, methodName);\n }\n await flushAndDispose(clientToDispose);\n };\n\n if (!wrapperOptions.spanName) {\n try {\n if (callback) {\n callback(...args);\n }\n\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(\n (res: unknown) => {\n waitUntil?.(teardown());\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?.(teardown());\n throw e;\n },\n );\n } else {\n waitUntil?.(teardown());\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?.(teardown());\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 const executeSpan = (): unknown => {\n return startSpan({ name: methodName, attributes }, span => {\n // When linking to previous trace, fetch the stored context and add links asynchronously\n // This avoids blocking the response while fetching from storage\n if (startNewTrace && storage) {\n waitUntil?.(\n getStoredSpanContext(storage, methodName).then(storedContext => {\n if (storedContext) {\n span.addLinks(buildSpanLinks(storedContext));\n // TODO: Remove this once EAP can store span links. We currently only set this attribute so that we\n // can obtain the previous trace information from the EAP store. Long-term, EAP will handle\n // span links and then we should remove this again. Also throwing in a TODO(v11), to remind us\n // to check this at v11 time :)\n const sampledFlag = storedContext.sampled ? '1' : '0';\n span.setAttribute(\n 'sentry.previous_trace',\n `${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}`,\n );\n }\n }),\n );\n }\n\n try {\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(\n (res: unknown) => {\n waitUntil?.(teardown());\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?.(teardown());\n throw e;\n },\n );\n } else {\n waitUntil?.(teardown());\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?.(teardown());\n throw e;\n }\n });\n };\n\n if (rpcMeta) {\n return continueTrace(\n { sentryTrace: rpcMeta['sentry-trace'] || '', baggage: rpcMeta.baggage || '' },\n executeSpan,\n );\n }\n\n if (startNewTrace) {\n return startNewTraceCore(() => executeSpan());\n }\n\n return executeSpan();\n };\n\n return sentryWithScope(wrappedFunction);\n },\n }),\n noMark,\n );\n}\n"],"names":["ensureInstrumented","rpcMeta","extractRpcMeta","getClient","withIsolationScope","withScope","init","storeSpanContext","flushAndDispose","isThenable","captureException","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","getStoredSpanContext","buildSpanLinks","continueTrace","startNewTraceCore"],"mappings":";;;;;;;;;AA2DO,SAAS,oBAAA,CACd,cAAA,EACA,OAAA,EACA,QAAA,EACA,MAAA,EACG;AACH,EAAA,OAAOA,6BAAA;AAAA,IACL,OAAA;AAAA,IACA,CAAA,QAAA,KACE,IAAI,KAAA,CAAM,QAAA,EAAU;AAAA,MAClB,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAwB;AAC7C,QAAA,MAAM,EAAE,eAAc,GAAI,cAAA;AAK1B,QAAA,IAAI,IAAA,GAAO,OAAA;AACX,QAAA,IAAIC,SAAA;AAEJ,QAAA,IAAI,cAAA,CAAe,WAAW,KAAA,EAAO;AACnC,UAAA,MAAM,SAAA,GAAYC,uBAAe,OAAO,CAAA;AACxC,UAAA,IAAA,GAAO,SAAA,CAAU,IAAA;AACjB,UAAAD,SAAA,GAAU,SAAA,CAAU,OAAA;AAAA,QACtB;AAIA,QAAA,MAAM,gBAAgBE,cAAA,EAAU;AAChC,QAAA,MAAM,eAAA,GAAkB,aAAA,GAAgBC,uBAAA,GAAqB,aAAA,GAAgBC,cAAA,GAAYD,uBAAA;AAEzF,QAAA,MAAM,eAAA,GAAkB,CAAC,KAAA,KAA6C;AAIpE,UAAA,MAAM,UAAqD,cAAA,CAAe,OAAA;AAE1E,UAAA,MAAM,SAAA,GAAY,OAAA,EAAS,SAAA,EAAW,IAAA,GAAO,OAAO,CAAA;AACpD,UAAA,MAAM,OAAA,GAAU,OAAA,IAAW,iBAAA,IAAqB,OAAA,GAAU,QAAQ,eAAA,GAAkB,MAAA;AAEpF,UAAA,IAAI,WAAA,GAAc,MAAM,SAAA,EAAU;AAKlC,UAAA,IAAI,aAAA,IAAiB,CAAC,WAAA,EAAa,YAAA,EAAa,EAAG;AACjD,YAAA,MAAM,SAASE,QAAA,CAAK;AAAA,cAClB,GAAG,cAAA,CAAe,OAAA;AAAA,cAClB,GAAA,EAAK;AAAA,aACN,CAAA;AACD,YAAA,KAAA,CAAM,UAAU,MAAM,CAAA;AACtB,YAAA,WAAA,GAAc,MAAA;AAAA,UAChB;AAEA,UAAA,MAAM,eAAA,GAAkB,WAAA;AACxB,UAAA,MAAM,UAAA,GAAa,eAAe,QAAA,IAAY,SAAA;AAE9C,UAAA,MAAM,WAAW,YAA2B;AAC1C,YAAA,IAAI,iBAAiB,OAAA,EAAS;AAC5B,cAAA,MAAMC,2BAAA,CAAiB,SAAS,UAAU,CAAA;AAAA,YAC5C;AACA,YAAA,MAAMC,sBAAgB,eAAe,CAAA;AAAA,UACvC,CAAA;AAEA,UAAA,IAAI,CAAC,eAAe,QAAA,EAAU;AAC5B,YAAA,IAAI;AACF,cAAA,IAAI,QAAA,EAAU;AACZ,gBAAA,QAAA,CAAS,GAAG,IAAI,CAAA;AAAA,cAClB;AAEA,cAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,IAAI,CAAA;AAElD,cAAA,IAAIC,eAAA,CAAW,MAAM,CAAA,EAAG;AACtB,gBAAA,OAAO,MAAA,CAAO,IAAA;AAAA,kBACZ,CAAC,GAAA,KAAiB;AAChB,oBAAA,SAAA,GAAY,UAAU,CAAA;AACtB,oBAAA,OAAO,GAAA;AAAA,kBACT,CAAA;AAAA,kBACA,CAAC,CAAA,KAAe;AACd,oBAAAC,qBAAA,CAAiB,CAAA,EAAG;AAAA,sBAClB,SAAA,EAAW;AAAA,wBACT,IAAA,EAAM,qCAAA;AAAA,wBACN,OAAA,EAAS;AAAA;AACX,qBACD,CAAA;AACD,oBAAA,SAAA,GAAY,UAAU,CAAA;AACtB,oBAAA,MAAM,CAAA;AAAA,kBACR;AAAA,iBACF;AAAA,cACF,CAAA,MAAO;AACL,gBAAA,SAAA,GAAY,UAAU,CAAA;AACtB,gBAAA,OAAO,MAAA;AAAA,cACT;AAAA,YACF,SAAS,CAAA,EAAG;AACV,cAAAA,qBAAA,CAAiB,CAAA,EAAG;AAAA,gBAClB,SAAA,EAAW;AAAA,kBACT,IAAA,EAAM,qCAAA;AAAA,kBACN,OAAA,EAAS;AAAA;AACX,eACD,CAAA;AACD,cAAA,SAAA,GAAY,UAAU,CAAA;AACtB,cAAA,MAAM,CAAA;AAAA,YACR;AAAA,UACF;AAEA,UAAA,MAAM,UAAA,GAAa,eAAe,MAAA,GAC9B;AAAA,YACE,CAACC,iCAA4B,GAAG,cAAA,CAAe,MAAA;AAAA,YAC/C,CAACC,qCAAgC,GAAG;AAAA,cAEtC,EAAC;AAEL,UAAA,MAAM,cAAc,MAAe;AACjC,YAAA,OAAOC,eAAU,EAAE,IAAA,EAAM,UAAA,EAAY,UAAA,IAAc,CAAA,IAAA,KAAQ;AAGzD,cAAA,IAAI,iBAAiB,OAAA,EAAS;AAC5B,gBAAA,SAAA;AAAA,kBACEC,+BAAA,CAAqB,OAAA,EAAS,UAAU,CAAA,CAAE,KAAK,CAAA,aAAA,KAAiB;AAC9D,oBAAA,IAAI,aAAA,EAAe;AACjB,sBAAA,IAAA,CAAK,QAAA,CAASC,yBAAA,CAAe,aAAa,CAAC,CAAA;AAK3C,sBAAA,MAAM,WAAA,GAAc,aAAA,CAAc,OAAA,GAAU,GAAA,GAAM,GAAA;AAClD,sBAAA,IAAA,CAAK,YAAA;AAAA,wBACH,uBAAA;AAAA,wBACA,GAAG,aAAA,CAAc,OAAO,IAAI,aAAA,CAAc,MAAM,IAAI,WAAW,CAAA;AAAA,uBACjE;AAAA,oBACF;AAAA,kBACF,CAAC;AAAA,iBACH;AAAA,cACF;AAEA,cAAA,IAAI;AACF,gBAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,IAAI,CAAA;AAElD,gBAAA,IAAIN,eAAA,CAAW,MAAM,CAAA,EAAG;AACtB,kBAAA,OAAO,MAAA,CAAO,IAAA;AAAA,oBACZ,CAAC,GAAA,KAAiB;AAChB,sBAAA,SAAA,GAAY,UAAU,CAAA;AACtB,sBAAA,OAAO,GAAA;AAAA,oBACT,CAAA;AAAA,oBACA,CAAC,CAAA,KAAe;AACd,sBAAAC,qBAAA,CAAiB,CAAA,EAAG;AAAA,wBAClB,SAAA,EAAW;AAAA,0BACT,IAAA,EAAM,qCAAA;AAAA,0BACN,OAAA,EAAS;AAAA;AACX,uBACD,CAAA;AACD,sBAAA,SAAA,GAAY,UAAU,CAAA;AACtB,sBAAA,MAAM,CAAA;AAAA,oBACR;AAAA,mBACF;AAAA,gBACF,CAAA,MAAO;AACL,kBAAA,SAAA,GAAY,UAAU,CAAA;AACtB,kBAAA,OAAO,MAAA;AAAA,gBACT;AAAA,cACF,SAAS,CAAA,EAAG;AACV,gBAAAA,qBAAA,CAAiB,CAAA,EAAG;AAAA,kBAClB,SAAA,EAAW;AAAA,oBACT,IAAA,EAAM,qCAAA;AAAA,oBACN,OAAA,EAAS;AAAA;AACX,iBACD,CAAA;AACD,gBAAA,SAAA,GAAY,UAAU,CAAA;AACtB,gBAAA,MAAM,CAAA;AAAA,cACR;AAAA,YACF,CAAC,CAAA;AAAA,UACH,CAAA;AAEA,UAAA,IAAIT,SAAA,EAAS;AACX,YAAA,OAAOe,kBAAA;AAAA,cACL,EAAE,aAAaf,SAAA,CAAQ,cAAc,KAAK,EAAA,EAAI,OAAA,EAASA,SAAA,CAAQ,OAAA,IAAW,EAAA,EAAG;AAAA,cAC7E;AAAA,aACF;AAAA,UACF;AAEA,UAAA,IAAI,aAAA,EAAe;AACjB,YAAA,OAAOgB,kBAAA,CAAkB,MAAM,WAAA,EAAa,CAAA;AAAA,UAC9C;AAEA,UAAA,OAAO,WAAA,EAAY;AAAA,QACrB,CAAA;AAEA,QAAA,OAAO,gBAAgB,eAAe,CAAA;AAAA,MACxC;AAAA,KACD,CAAA;AAAA,IACH;AAAA,GACF;AACF;;;;"}
|
package/build/esm/async.js
CHANGED
|
@@ -1,38 +1,18 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
import { setAsyncContextStrategy, getDefaultIsolationScope, getDefaultCurrentScope } from '@sentry/core';
|
|
3
3
|
|
|
4
|
-
// Need to use node: prefix for cloudflare workers compatibility
|
|
5
|
-
// Note: Because we are using node:async_hooks, we need to set `node_compat` in the wrangler.toml
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Sets the async context strategy to use AsyncLocalStorage.
|
|
9
|
-
*
|
|
10
|
-
* AsyncLocalStorage is only available in the cloudflare workers runtime if you set
|
|
11
|
-
* compatibility_flags = ["nodejs_compat"] or compatibility_flags = ["nodejs_als"]
|
|
12
|
-
*
|
|
13
|
-
* @internal Only exported to be used in higher-level Sentry packages
|
|
14
|
-
* @hidden Only exported to be used in higher-level Sentry packages
|
|
15
|
-
*/
|
|
16
4
|
function setAsyncLocalStorageAsyncContextStrategy() {
|
|
17
|
-
const asyncStorage = new AsyncLocalStorage
|
|
18
|
-
|
|
19
|
-
();
|
|
20
|
-
|
|
5
|
+
const asyncStorage = new AsyncLocalStorage();
|
|
21
6
|
function getScopes() {
|
|
22
7
|
const scopes = asyncStorage.getStore();
|
|
23
|
-
|
|
24
8
|
if (scopes) {
|
|
25
9
|
return scopes;
|
|
26
10
|
}
|
|
27
|
-
|
|
28
|
-
// fallback behavior:
|
|
29
|
-
// if, for whatever reason, we can't find scopes on the context here, we have to fix this somehow
|
|
30
11
|
return {
|
|
31
12
|
scope: getDefaultCurrentScope(),
|
|
32
|
-
isolationScope: getDefaultIsolationScope()
|
|
13
|
+
isolationScope: getDefaultIsolationScope()
|
|
33
14
|
};
|
|
34
15
|
}
|
|
35
|
-
|
|
36
16
|
function withScope(callback) {
|
|
37
17
|
const scope = getScopes().scope.clone();
|
|
38
18
|
const isolationScope = getScopes().isolationScope;
|
|
@@ -40,14 +20,12 @@ function setAsyncLocalStorageAsyncContextStrategy() {
|
|
|
40
20
|
return callback(scope);
|
|
41
21
|
});
|
|
42
22
|
}
|
|
43
|
-
|
|
44
23
|
function withSetScope(scope, callback) {
|
|
45
24
|
const isolationScope = getScopes().isolationScope.clone();
|
|
46
25
|
return asyncStorage.run({ scope, isolationScope }, () => {
|
|
47
26
|
return callback(scope);
|
|
48
27
|
});
|
|
49
28
|
}
|
|
50
|
-
|
|
51
29
|
function withIsolationScope(callback) {
|
|
52
30
|
const scope = getScopes().scope;
|
|
53
31
|
const isolationScope = getScopes().isolationScope.clone();
|
|
@@ -55,22 +33,18 @@ function setAsyncLocalStorageAsyncContextStrategy() {
|
|
|
55
33
|
return callback(isolationScope);
|
|
56
34
|
});
|
|
57
35
|
}
|
|
58
|
-
|
|
59
36
|
function withSetIsolationScope(isolationScope, callback) {
|
|
60
37
|
const scope = getScopes().scope;
|
|
61
38
|
return asyncStorage.run({ scope, isolationScope }, () => {
|
|
62
39
|
return callback(isolationScope);
|
|
63
40
|
});
|
|
64
41
|
}
|
|
65
|
-
|
|
66
|
-
// In contrast to the browser, we can rely on async context isolation here
|
|
67
42
|
function suppressTracing(callback) {
|
|
68
|
-
return withScope(scope => {
|
|
43
|
+
return withScope((scope) => {
|
|
69
44
|
scope.setSDKProcessingMetadata({ __SENTRY_SUPPRESS_TRACING__: true });
|
|
70
45
|
return callback();
|
|
71
46
|
});
|
|
72
47
|
}
|
|
73
|
-
|
|
74
48
|
setAsyncContextStrategy({
|
|
75
49
|
suppressTracing,
|
|
76
50
|
withScope,
|
|
@@ -78,7 +52,7 @@ function setAsyncLocalStorageAsyncContextStrategy() {
|
|
|
78
52
|
withIsolationScope,
|
|
79
53
|
withSetIsolationScope,
|
|
80
54
|
getCurrentScope: () => getScopes().scope,
|
|
81
|
-
getIsolationScope: () => getScopes().isolationScope
|
|
55
|
+
getIsolationScope: () => getScopes().isolationScope
|
|
82
56
|
});
|
|
83
57
|
}
|
|
84
58
|
|
package/build/esm/async.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async.js","sources":["../../src/async.ts"],"sourcesContent":["// Need to use node: prefix for cloudflare workers compatibility\n// Note: Because we are using node:async_hooks, we need to set `node_compat` in the wrangler.toml\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Scope } from '@sentry/core';\nimport { getDefaultCurrentScope, getDefaultIsolationScope, setAsyncContextStrategy } from '@sentry/core';\n\n/**\n * Sets the async context strategy to use AsyncLocalStorage.\n *\n * AsyncLocalStorage is only available in the cloudflare workers runtime if you set\n * compatibility_flags = [\"nodejs_compat\"] or compatibility_flags = [\"nodejs_als\"]\n *\n * @internal Only exported to be used in higher-level Sentry packages\n * @hidden Only exported to be used in higher-level Sentry packages\n */\nexport function setAsyncLocalStorageAsyncContextStrategy(): void {\n const asyncStorage = new AsyncLocalStorage<{\n scope: Scope;\n isolationScope: Scope;\n }>();\n\n function getScopes(): { scope: Scope; isolationScope: Scope } {\n const scopes = asyncStorage.getStore();\n\n if (scopes) {\n return scopes;\n }\n\n // fallback behavior:\n // if, for whatever reason, we can't find scopes on the context here, we have to fix this somehow\n return {\n scope: getDefaultCurrentScope(),\n isolationScope: getDefaultIsolationScope(),\n };\n }\n\n function withScope<T>(callback: (scope: Scope) => T): T {\n const scope = getScopes().scope.clone();\n const isolationScope = getScopes().isolationScope;\n return asyncStorage.run({ scope, isolationScope }, () => {\n return callback(scope);\n });\n }\n\n function withSetScope<T>(scope: Scope, callback: (scope: Scope) => T): T {\n const isolationScope = getScopes().isolationScope.clone();\n return asyncStorage.run({ scope, isolationScope }, () => {\n return callback(scope);\n });\n }\n\n function withIsolationScope<T>(callback: (isolationScope: Scope) => T): T {\n const scope = getScopes().scope;\n const isolationScope = getScopes().isolationScope.clone();\n return asyncStorage.run({ scope, isolationScope }, () => {\n return callback(isolationScope);\n });\n }\n\n function withSetIsolationScope<T>(isolationScope: Scope, callback: (isolationScope: Scope) => T): T {\n const scope = getScopes().scope;\n return asyncStorage.run({ scope, isolationScope }, () => {\n return callback(isolationScope);\n });\n }\n\n // In contrast to the browser, we can rely on async context isolation here\n function suppressTracing<T>(callback: () => T): T {\n return withScope(scope => {\n scope.setSDKProcessingMetadata({ __SENTRY_SUPPRESS_TRACING__: true });\n return callback();\n });\n }\n\n setAsyncContextStrategy({\n suppressTracing,\n withScope,\n withSetScope,\n withIsolationScope,\n withSetIsolationScope,\n getCurrentScope: () => getScopes().scope,\n getIsolationScope: () => getScopes().isolationScope,\n });\n}\n"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"async.js","sources":["../../src/async.ts"],"sourcesContent":["// Need to use node: prefix for cloudflare workers compatibility\n// Note: Because we are using node:async_hooks, we need to set `node_compat` in the wrangler.toml\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Scope } from '@sentry/core';\nimport { getDefaultCurrentScope, getDefaultIsolationScope, setAsyncContextStrategy } from '@sentry/core';\n\n/**\n * Sets the async context strategy to use AsyncLocalStorage.\n *\n * AsyncLocalStorage is only available in the cloudflare workers runtime if you set\n * compatibility_flags = [\"nodejs_compat\"] or compatibility_flags = [\"nodejs_als\"]\n *\n * @internal Only exported to be used in higher-level Sentry packages\n * @hidden Only exported to be used in higher-level Sentry packages\n */\nexport function setAsyncLocalStorageAsyncContextStrategy(): void {\n const asyncStorage = new AsyncLocalStorage<{\n scope: Scope;\n isolationScope: Scope;\n }>();\n\n function getScopes(): { scope: Scope; isolationScope: Scope } {\n const scopes = asyncStorage.getStore();\n\n if (scopes) {\n return scopes;\n }\n\n // fallback behavior:\n // if, for whatever reason, we can't find scopes on the context here, we have to fix this somehow\n return {\n scope: getDefaultCurrentScope(),\n isolationScope: getDefaultIsolationScope(),\n };\n }\n\n function withScope<T>(callback: (scope: Scope) => T): T {\n const scope = getScopes().scope.clone();\n const isolationScope = getScopes().isolationScope;\n return asyncStorage.run({ scope, isolationScope }, () => {\n return callback(scope);\n });\n }\n\n function withSetScope<T>(scope: Scope, callback: (scope: Scope) => T): T {\n const isolationScope = getScopes().isolationScope.clone();\n return asyncStorage.run({ scope, isolationScope }, () => {\n return callback(scope);\n });\n }\n\n function withIsolationScope<T>(callback: (isolationScope: Scope) => T): T {\n const scope = getScopes().scope;\n const isolationScope = getScopes().isolationScope.clone();\n return asyncStorage.run({ scope, isolationScope }, () => {\n return callback(isolationScope);\n });\n }\n\n function withSetIsolationScope<T>(isolationScope: Scope, callback: (isolationScope: Scope) => T): T {\n const scope = getScopes().scope;\n return asyncStorage.run({ scope, isolationScope }, () => {\n return callback(isolationScope);\n });\n }\n\n // In contrast to the browser, we can rely on async context isolation here\n function suppressTracing<T>(callback: () => T): T {\n return withScope(scope => {\n scope.setSDKProcessingMetadata({ __SENTRY_SUPPRESS_TRACING__: true });\n return callback();\n });\n }\n\n setAsyncContextStrategy({\n suppressTracing,\n withScope,\n withSetScope,\n withIsolationScope,\n withSetIsolationScope,\n getCurrentScope: () => getScopes().scope,\n getIsolationScope: () => getScopes().isolationScope,\n });\n}\n"],"names":[],"mappings":";;;AAeO,SAAS,wCAAA,GAAiD;AAC/D,EAAA,MAAM,YAAA,GAAe,IAAI,iBAAA,EAGtB;AAEH,EAAA,SAAS,SAAA,GAAqD;AAC5D,IAAA,MAAM,MAAA,GAAS,aAAa,QAAA,EAAS;AAErC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAO,MAAA;AAAA,IACT;AAIA,IAAA,OAAO;AAAA,MACL,OAAO,sBAAA,EAAuB;AAAA,MAC9B,gBAAgB,wBAAA;AAAyB,KAC3C;AAAA,EACF;AAEA,EAAA,SAAS,UAAa,QAAA,EAAkC;AACtD,IAAA,MAAM,KAAA,GAAQ,SAAA,EAAU,CAAE,KAAA,CAAM,KAAA,EAAM;AACtC,IAAA,MAAM,cAAA,GAAiB,WAAU,CAAE,cAAA;AACnC,IAAA,OAAO,aAAa,GAAA,CAAI,EAAE,KAAA,EAAO,cAAA,IAAkB,MAAM;AACvD,MAAA,OAAO,SAAS,KAAK,CAAA;AAAA,IACvB,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,SAAS,YAAA,CAAgB,OAAc,QAAA,EAAkC;AACvE,IAAA,MAAM,cAAA,GAAiB,SAAA,EAAU,CAAE,cAAA,CAAe,KAAA,EAAM;AACxD,IAAA,OAAO,aAAa,GAAA,CAAI,EAAE,KAAA,EAAO,cAAA,IAAkB,MAAM;AACvD,MAAA,OAAO,SAAS,KAAK,CAAA;AAAA,IACvB,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,SAAS,mBAAsB,QAAA,EAA2C;AACxE,IAAA,MAAM,KAAA,GAAQ,WAAU,CAAE,KAAA;AAC1B,IAAA,MAAM,cAAA,GAAiB,SAAA,EAAU,CAAE,cAAA,CAAe,KAAA,EAAM;AACxD,IAAA,OAAO,aAAa,GAAA,CAAI,EAAE,KAAA,EAAO,cAAA,IAAkB,MAAM;AACvD,MAAA,OAAO,SAAS,cAAc,CAAA;AAAA,IAChC,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,SAAS,qBAAA,CAAyB,gBAAuB,QAAA,EAA2C;AAClG,IAAA,MAAM,KAAA,GAAQ,WAAU,CAAE,KAAA;AAC1B,IAAA,OAAO,aAAa,GAAA,CAAI,EAAE,KAAA,EAAO,cAAA,IAAkB,MAAM;AACvD,MAAA,OAAO,SAAS,cAAc,CAAA;AAAA,IAChC,CAAC,CAAA;AAAA,EACH;AAGA,EAAA,SAAS,gBAAmB,QAAA,EAAsB;AAChD,IAAA,OAAO,UAAU,CAAA,KAAA,KAAS;AACxB,MAAA,KAAA,CAAM,wBAAA,CAAyB,EAAE,2BAAA,EAA6B,IAAA,EAAM,CAAA;AACpE,MAAA,OAAO,QAAA,EAAS;AAAA,IAClB,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,uBAAA,CAAwB;AAAA,IACtB,eAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA,kBAAA;AAAA,IACA,qBAAA;AAAA,IACA,eAAA,EAAiB,MAAM,SAAA,EAAU,CAAE,KAAA;AAAA,IACnC,iBAAA,EAAmB,MAAM,SAAA,EAAU,CAAE;AAAA,GACtC,CAAA;AACH;;;;"}
|