@sentry/cloudflare 10.43.0 → 10.44.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/index.js +3 -2
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentEmail.js +80 -0
- package/build/cjs/instrumentations/worker/instrumentEmail.js.map +1 -0
- package/build/cjs/instrumentations/worker/instrumentFetch.js +36 -0
- package/build/cjs/instrumentations/worker/instrumentFetch.js.map +1 -0
- package/build/cjs/instrumentations/worker/instrumentQueue.js +85 -0
- package/build/cjs/instrumentations/worker/instrumentQueue.js.map +1 -0
- package/build/cjs/instrumentations/worker/instrumentScheduled.js +82 -0
- package/build/cjs/instrumentations/worker/instrumentScheduled.js.map +1 -0
- package/build/cjs/instrumentations/worker/instrumentTail.js +63 -0
- package/build/cjs/instrumentations/worker/instrumentTail.js.map +1 -0
- package/build/cjs/request.js +1 -1
- package/build/cjs/request.js.map +1 -1
- package/build/cjs/withSentry.js +66 -0
- package/build/cjs/withSentry.js.map +1 -0
- package/build/cjs/wrapMethodWithSentry.js +7 -3
- package/build/cjs/wrapMethodWithSentry.js.map +1 -1
- package/build/esm/index.js +2 -2
- package/build/esm/instrumentations/worker/instrumentEmail.js +78 -0
- package/build/esm/instrumentations/worker/instrumentEmail.js.map +1 -0
- package/build/esm/instrumentations/worker/instrumentFetch.js +34 -0
- package/build/esm/instrumentations/worker/instrumentFetch.js.map +1 -0
- package/build/esm/instrumentations/worker/instrumentQueue.js +83 -0
- package/build/esm/instrumentations/worker/instrumentQueue.js.map +1 -0
- package/build/esm/instrumentations/worker/instrumentScheduled.js +80 -0
- package/build/esm/instrumentations/worker/instrumentScheduled.js.map +1 -0
- package/build/esm/instrumentations/worker/instrumentTail.js +61 -0
- package/build/esm/instrumentations/worker/instrumentTail.js.map +1 -0
- package/build/esm/package.json +1 -1
- package/build/esm/request.js +1 -1
- package/build/esm/request.js.map +1 -1
- package/build/esm/withSentry.js +64 -0
- package/build/esm/withSentry.js.map +1 -0
- package/build/esm/wrapMethodWithSentry.js +7 -3
- package/build/esm/wrapMethodWithSentry.js.map +1 -1
- package/build/types/index.d.ts +2 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentEmail.d.ts +7 -0
- package/build/types/instrumentations/worker/instrumentEmail.d.ts.map +1 -0
- package/build/types/instrumentations/worker/instrumentFetch.d.ts +7 -0
- package/build/types/instrumentations/worker/instrumentFetch.d.ts.map +1 -0
- package/build/types/instrumentations/worker/instrumentQueue.d.ts +7 -0
- package/build/types/instrumentations/worker/instrumentQueue.d.ts.map +1 -0
- package/build/types/instrumentations/worker/instrumentScheduled.d.ts +7 -0
- package/build/types/instrumentations/worker/instrumentScheduled.d.ts.map +1 -0
- package/build/types/instrumentations/worker/instrumentTail.d.ts +7 -0
- package/build/types/instrumentations/worker/instrumentTail.d.ts.map +1 -0
- package/build/types/{handler.d.ts → withSentry.d.ts} +1 -1
- package/build/types/withSentry.d.ts.map +1 -0
- package/build/types/wrapMethodWithSentry.d.ts.map +1 -1
- package/build/types-ts3.8/index.d.ts +2 -2
- package/build/types-ts3.8/instrumentations/worker/instrumentEmail.d.ts +7 -0
- package/build/types-ts3.8/instrumentations/worker/instrumentFetch.d.ts +7 -0
- package/build/types-ts3.8/instrumentations/worker/instrumentQueue.d.ts +7 -0
- package/build/types-ts3.8/instrumentations/worker/instrumentScheduled.d.ts +7 -0
- package/build/types-ts3.8/instrumentations/worker/instrumentTail.d.ts +7 -0
- package/build/types-ts3.8/{handler.d.ts → withSentry.d.ts} +1 -1
- package/package.json +4 -4
- package/build/cjs/handler.js +0 -251
- package/build/cjs/handler.js.map +0 -1
- package/build/esm/handler.js +0 -249
- package/build/esm/handler.js.map +0 -1
- package/build/types/handler.d.ts.map +0 -1
package/build/cjs/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
|
|
3
3
|
const core = require('@sentry/core');
|
|
4
|
-
const
|
|
4
|
+
const withSentry = require('./withSentry.js');
|
|
5
5
|
const durableobject = require('./durableobject.js');
|
|
6
6
|
const pagesPlugin = require('./pages-plugin.js');
|
|
7
7
|
const request = require('./request.js');
|
|
@@ -72,6 +72,7 @@ exports.moduleMetadataIntegration = core.moduleMetadataIntegration;
|
|
|
72
72
|
exports.requestDataIntegration = core.requestDataIntegration;
|
|
73
73
|
exports.rewriteFramesIntegration = core.rewriteFramesIntegration;
|
|
74
74
|
exports.setContext = core.setContext;
|
|
75
|
+
exports.setConversationId = core.setConversationId;
|
|
75
76
|
exports.setCurrentClient = core.setCurrentClient;
|
|
76
77
|
exports.setExtra = core.setExtra;
|
|
77
78
|
exports.setExtras = core.setExtras;
|
|
@@ -97,7 +98,7 @@ exports.withMonitor = core.withMonitor;
|
|
|
97
98
|
exports.withScope = core.withScope;
|
|
98
99
|
exports.wrapMcpServerWithSentry = core.wrapMcpServerWithSentry;
|
|
99
100
|
exports.zodErrorsIntegration = core.zodErrorsIntegration;
|
|
100
|
-
exports.withSentry =
|
|
101
|
+
exports.withSentry = withSentry.withSentry;
|
|
101
102
|
exports.instrumentDurableObjectWithSentry = durableobject.instrumentDurableObjectWithSentry;
|
|
102
103
|
exports.sentryPagesPlugin = pagesPlugin.sentryPagesPlugin;
|
|
103
104
|
exports.wrapRequestHandler = request.wrapRequestHandler;
|
package/build/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const core = require('@sentry/core');
|
|
4
|
+
const flush = require('../../flush.js');
|
|
5
|
+
const instrument = require('../../instrument.js');
|
|
6
|
+
const options = require('../../options.js');
|
|
7
|
+
const scopeUtils = require('../../scope-utils.js');
|
|
8
|
+
const sdk = require('../../sdk.js');
|
|
9
|
+
const instrumentContext = require('../../utils/instrumentContext.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Core email handler logic - wraps execution with Sentry instrumentation.
|
|
13
|
+
*/
|
|
14
|
+
function wrapEmailHandler(
|
|
15
|
+
emailMessage,
|
|
16
|
+
options,
|
|
17
|
+
context,
|
|
18
|
+
fn,
|
|
19
|
+
) {
|
|
20
|
+
return core.withIsolationScope(isolationScope => {
|
|
21
|
+
const waitUntil = context.waitUntil.bind(context);
|
|
22
|
+
|
|
23
|
+
const client = sdk.init({ ...options, ctx: context });
|
|
24
|
+
isolationScope.setClient(client);
|
|
25
|
+
|
|
26
|
+
scopeUtils.addCloudResourceContext(isolationScope);
|
|
27
|
+
|
|
28
|
+
return core.startSpan(
|
|
29
|
+
{
|
|
30
|
+
op: 'faas.email',
|
|
31
|
+
name: `Handle Email ${emailMessage.to}`,
|
|
32
|
+
attributes: {
|
|
33
|
+
'faas.trigger': 'email',
|
|
34
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.email',
|
|
35
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
async () => {
|
|
39
|
+
try {
|
|
40
|
+
return await fn();
|
|
41
|
+
} catch (e) {
|
|
42
|
+
core.captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.email' } });
|
|
43
|
+
throw e;
|
|
44
|
+
} finally {
|
|
45
|
+
waitUntil(flush.flushAndDispose(client));
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Instruments an email handler for ExportedHandler (env/ctx come from args).
|
|
54
|
+
*/
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
56
|
+
function instrumentExportedHandlerEmail(
|
|
57
|
+
handler,
|
|
58
|
+
optionsCallback,
|
|
59
|
+
) {
|
|
60
|
+
if (!('email' in handler) || typeof handler.email !== 'function' || instrument.isInstrumented(handler.email)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
handler.email = new Proxy(handler.email, {
|
|
65
|
+
apply(target, thisArg, args) {
|
|
66
|
+
const [emailMessage, env, ctx] = args;
|
|
67
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
68
|
+
args[2] = context;
|
|
69
|
+
|
|
70
|
+
const options$1 = options.getFinalOptions(optionsCallback(env), env);
|
|
71
|
+
|
|
72
|
+
return wrapEmailHandler(emailMessage, options$1, context, () => target.apply(thisArg, args));
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
instrument.markAsInstrumented(handler.email);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
exports.instrumentExportedHandlerEmail = instrumentExportedHandlerEmail;
|
|
80
|
+
//# sourceMappingURL=instrumentEmail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentEmail.js","sources":["../../../../src/instrumentations/worker/instrumentEmail.ts"],"sourcesContent":["import type { EmailMessage, ExportedHandler } from '@cloudflare/workers-types';\nimport {\n captureException,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n withIsolationScope,\n} from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { isInstrumented, markAsInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\n\n/**\n * Core email handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapEmailHandler(\n emailMessage: EmailMessage,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.email',\n name: `Handle Email ${emailMessage.to}`,\n attributes: {\n 'faas.trigger': 'email',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.email',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.email' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments an email handler for ExportedHandler (env/ctx come from args).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentExportedHandlerEmail<T extends ExportedHandler<any, any, any>>(\n handler: T,\n optionsCallback: (env: Parameters<NonNullable<T['email']>>[1]) => CloudflareOptions | undefined,\n): void {\n if (!('email' in handler) || typeof handler.email !== 'function' || isInstrumented(handler.email)) {\n return;\n }\n\n handler.email = new Proxy(handler.email, {\n apply(target, thisArg, args: Parameters<NonNullable<T['email']>>) {\n const [emailMessage, env, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n return wrapEmailHandler(emailMessage, options, context, () => target.apply(thisArg, args));\n },\n });\n\n markAsInstrumented(handler.email);\n}\n"],"names":["withIsolationScope","init","addCloudResourceContext","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","captureException","flushAndDispose","isInstrumented","instrumentContext","options","getFinalOptions","markAsInstrumented"],"mappings":";;;;;;;;;;AAgBA;AACA;AACA;AACA,SAAS,gBAAgB;AACzB,EAAE,YAAY;AACd,EAAE,OAAO;AACT,EAAE,OAAO;AACT,EAAE,EAAE;AACJ,EAAW;AACX,EAAE,OAAOA,uBAAkB,CAAC,cAAA,IAAkB;AAC9C,IAAI,MAAM,SAAA,GAAY,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;;AAErD,IAAI,MAAM,MAAA,GAASC,QAAI,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,OAAA,EAAS,CAAC;AACrD,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC;;AAEpC,IAAIC,kCAAuB,CAAC,cAAc,CAAC;;AAE3C,IAAI,OAAOC,cAAS;AACpB,MAAM;AACN,QAAQ,EAAE,EAAE,YAAY;AACxB,QAAQ,IAAI,EAAE,CAAC,aAAa,EAAE,YAAY,CAAC,EAAE,CAAC,CAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,cAAA,EAAA,OAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,4BAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,MAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,YAAA;AACA,QAAA,IAAA;AACA,UAAA,OAAA,MAAA,EAAA,EAAA;AACA,QAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,UAAAC,qBAAA,CAAA,CAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,KAAA,EAAA,IAAA,EAAA,4BAAA,EAAA,EAAA,CAAA;AACA,UAAA,MAAA,CAAA;AACA,QAAA,CAAA,SAAA;AACA,UAAA,SAAA,CAAAC,qBAAA,CAAA,MAAA,CAAA,CAAA;AACA,QAAA;AACA,MAAA,CAAA;AACA,KAAA;AACA,EAAA,CAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,8BAAA;AACA,EAAA,OAAA;AACA,EAAA,eAAA;AACA,EAAA;AACA,EAAA,IAAA,EAAA,OAAA,IAAA,OAAA,CAAA,IAAA,OAAA,OAAA,CAAA,KAAA,KAAA,UAAA,IAAAC,yBAAA,CAAA,OAAA,CAAA,KAAA,CAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,OAAA,CAAA,KAAA,GAAA,IAAA,KAAA,CAAA,OAAA,CAAA,KAAA,EAAA;AACA,IAAA,KAAA,CAAA,MAAA,EAAA,OAAA,EAAA,IAAA,EAAA;AACA,MAAA,MAAA,CAAA,YAAA,EAAA,GAAA,EAAA,GAAA,CAAA,GAAA,IAAA;AACA,MAAA,MAAA,OAAA,GAAAC,mCAAA,CAAA,GAAA,CAAA;AACA,MAAA,IAAA,CAAA,CAAA,CAAA,GAAA,OAAA;;AAEA,MAAA,MAAAC,SAAA,GAAAC,uBAAA,CAAA,eAAA,CAAA,GAAA,CAAA,EAAA,GAAA,CAAA;;AAEA,MAAA,OAAA,gBAAA,CAAA,YAAA,EAAAD,SAAA,EAAA,OAAA,EAAA,MAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA,CAAA;AACA,IAAA,CAAA;AACA,GAAA,CAAA;;AAEA,EAAAE,6BAAA,CAAA,OAAA,CAAA,KAAA,CAAA;AACA;;;;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const instrument = require('../../instrument.js');
|
|
4
|
+
const options = require('../../options.js');
|
|
5
|
+
const request = require('../../request.js');
|
|
6
|
+
const instrumentContext = require('../../utils/instrumentContext.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Instruments a fetch handler for ExportedHandler (env/ctx come from args).
|
|
10
|
+
*/
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
function instrumentExportedHandlerFetch(
|
|
13
|
+
handler,
|
|
14
|
+
optionsCallback,
|
|
15
|
+
) {
|
|
16
|
+
if (!('fetch' in handler) || typeof handler.fetch !== 'function' || instrument.isInstrumented(handler.fetch)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
handler.fetch = new Proxy(handler.fetch, {
|
|
21
|
+
apply(target, thisArg, args) {
|
|
22
|
+
const [request$1, env, ctx] = args;
|
|
23
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
24
|
+
args[2] = context;
|
|
25
|
+
|
|
26
|
+
const options$1 = options.getFinalOptions(optionsCallback(env), env);
|
|
27
|
+
|
|
28
|
+
return request.wrapRequestHandler({ options: options$1, request: request$1, context }, () => target.apply(thisArg, args));
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
instrument.markAsInstrumented(handler.fetch);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
exports.instrumentExportedHandlerFetch = instrumentExportedHandlerFetch;
|
|
36
|
+
//# sourceMappingURL=instrumentFetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentFetch.js","sources":["../../../../src/instrumentations/worker/instrumentFetch.ts"],"sourcesContent":["import type { ExportedHandler } from '@cloudflare/workers-types';\nimport type { CloudflareOptions } from '../../client';\nimport { isInstrumented, markAsInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { wrapRequestHandler } from '../../request';\nimport { instrumentContext } from '../../utils/instrumentContext';\n\n/**\n * Instruments a fetch handler for ExportedHandler (env/ctx come from args).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentExportedHandlerFetch<T extends ExportedHandler<any, any, any>>(\n handler: T,\n optionsCallback: (env: Parameters<NonNullable<T['fetch']>>[1]) => CloudflareOptions | undefined,\n): void {\n if (!('fetch' in handler) || typeof handler.fetch !== 'function' || isInstrumented(handler.fetch)) {\n return;\n }\n\n handler.fetch = new Proxy(handler.fetch, {\n apply(target, thisArg, args: Parameters<NonNullable<T['fetch']>>) {\n const [request, env, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n return wrapRequestHandler({ options, request, context }, () => target.apply(thisArg, args));\n },\n });\n\n markAsInstrumented(handler.fetch);\n}\n"],"names":["isInstrumented","request","instrumentContext","options","getFinalOptions","wrapRequestHandler","markAsInstrumented"],"mappings":";;;;;;;AAOA;AACA;AACA;AACA;AACO,SAAS,8BAA8B;AAC9C,EAAE,OAAO;AACT,EAAE,eAAe;AACjB,EAAQ;AACR,EAAE,IAAI,EAAE,WAAW,OAAO,CAAA,IAAK,OAAO,OAAO,CAAC,KAAA,KAAU,cAAcA,yBAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACrG,IAAI;AACJ,EAAE;;AAEF,EAAE,OAAO,CAAC,KAAA,GAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE;AAC3C,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAuC;AACtE,MAAM,MAAM,CAACC,SAAO,EAAE,GAAG,EAAE,GAAG,CAAA,GAAI,IAAI;AACtC,MAAM,MAAM,OAAA,GAAUC,mCAAiB,CAAC,GAAG,CAAC;AAC5C,MAAM,IAAI,CAAC,CAAC,CAAA,GAAI,OAAO;;AAEvB,MAAM,MAAMC,SAAA,GAAUC,uBAAe,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;;AAEhE,MAAM,OAAOC,0BAAkB,CAAC,WAAEF,SAAO,WAAEF,SAAO,EAAE,OAAA,EAAS,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACjG,IAAI,CAAC;AACL,GAAG,CAAC;;AAEJ,EAAEK,6BAAkB,CAAC,OAAO,CAAC,KAAK,CAAC;AACnC;;;;"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const core = require('@sentry/core');
|
|
4
|
+
const flush = require('../../flush.js');
|
|
5
|
+
const instrument = require('../../instrument.js');
|
|
6
|
+
const options = require('../../options.js');
|
|
7
|
+
const scopeUtils = require('../../scope-utils.js');
|
|
8
|
+
const sdk = require('../../sdk.js');
|
|
9
|
+
const instrumentContext = require('../../utils/instrumentContext.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Core queue handler logic - wraps execution with Sentry instrumentation.
|
|
13
|
+
*/
|
|
14
|
+
function wrapQueueHandler(
|
|
15
|
+
batch,
|
|
16
|
+
options,
|
|
17
|
+
context,
|
|
18
|
+
fn,
|
|
19
|
+
) {
|
|
20
|
+
return core.withIsolationScope(isolationScope => {
|
|
21
|
+
const waitUntil = context.waitUntil.bind(context);
|
|
22
|
+
|
|
23
|
+
const client = sdk.init({ ...options, ctx: context });
|
|
24
|
+
isolationScope.setClient(client);
|
|
25
|
+
|
|
26
|
+
scopeUtils.addCloudResourceContext(isolationScope);
|
|
27
|
+
|
|
28
|
+
return core.startSpan(
|
|
29
|
+
{
|
|
30
|
+
op: 'faas.queue',
|
|
31
|
+
name: `process ${batch.queue}`,
|
|
32
|
+
attributes: {
|
|
33
|
+
'faas.trigger': 'pubsub',
|
|
34
|
+
'messaging.destination.name': batch.queue,
|
|
35
|
+
'messaging.system': 'cloudflare',
|
|
36
|
+
'messaging.batch.message_count': batch.messages.length,
|
|
37
|
+
'messaging.message.retry.count': batch.messages.reduce((acc, message) => acc + message.attempts - 1, 0),
|
|
38
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'queue.process',
|
|
39
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.queue',
|
|
40
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
async () => {
|
|
44
|
+
try {
|
|
45
|
+
return await fn();
|
|
46
|
+
} catch (e) {
|
|
47
|
+
core.captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.queue' } });
|
|
48
|
+
throw e;
|
|
49
|
+
} finally {
|
|
50
|
+
waitUntil(flush.flushAndDispose(client));
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Instruments a queue handler for ExportedHandler (env/ctx come from args).
|
|
59
|
+
*/
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
+
function instrumentExportedHandlerQueue(
|
|
62
|
+
handler,
|
|
63
|
+
optionsCallback,
|
|
64
|
+
) {
|
|
65
|
+
if (!('queue' in handler) || typeof handler.queue !== 'function' || instrument.isInstrumented(handler.queue)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
handler.queue = new Proxy(handler.queue, {
|
|
70
|
+
apply(target, thisArg, args) {
|
|
71
|
+
const [batch, env, ctx] = args;
|
|
72
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
73
|
+
args[2] = context;
|
|
74
|
+
|
|
75
|
+
const options$1 = options.getFinalOptions(optionsCallback(env), env);
|
|
76
|
+
|
|
77
|
+
return wrapQueueHandler(batch, options$1, context, () => target.apply(thisArg, args));
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
instrument.markAsInstrumented(handler.queue);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
exports.instrumentExportedHandlerQueue = instrumentExportedHandlerQueue;
|
|
85
|
+
//# sourceMappingURL=instrumentQueue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentQueue.js","sources":["../../../../src/instrumentations/worker/instrumentQueue.ts"],"sourcesContent":["import type { ExportedHandler, MessageBatch } from '@cloudflare/workers-types';\nimport {\n captureException,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n withIsolationScope,\n} from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { isInstrumented, markAsInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\n\n/**\n * Core queue handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapQueueHandler(\n batch: MessageBatch,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.queue',\n name: `process ${batch.queue}`,\n attributes: {\n 'faas.trigger': 'pubsub',\n 'messaging.destination.name': batch.queue,\n 'messaging.system': 'cloudflare',\n 'messaging.batch.message_count': batch.messages.length,\n 'messaging.message.retry.count': batch.messages.reduce((acc, message) => acc + message.attempts - 1, 0),\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'queue.process',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.queue',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.queue' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a queue handler for ExportedHandler (env/ctx come from args).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentExportedHandlerQueue<T extends ExportedHandler<any, any, any>>(\n handler: T,\n optionsCallback: (env: Parameters<NonNullable<T['queue']>>[1]) => CloudflareOptions | undefined,\n): void {\n if (!('queue' in handler) || typeof handler.queue !== 'function' || isInstrumented(handler.queue)) {\n return;\n }\n\n handler.queue = new Proxy(handler.queue, {\n apply(target, thisArg, args: Parameters<NonNullable<T['queue']>>) {\n const [batch, env, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n return wrapQueueHandler(batch, options, context, () => target.apply(thisArg, args));\n },\n });\n\n markAsInstrumented(handler.queue);\n}\n"],"names":["withIsolationScope","init","addCloudResourceContext","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","captureException","flushAndDispose","isInstrumented","instrumentContext","options","getFinalOptions","markAsInstrumented"],"mappings":";;;;;;;;;;AAiBA;AACA;AACA;AACA,SAAS,gBAAgB;AACzB,EAAE,KAAK;AACP,EAAE,OAAO;AACT,EAAE,OAAO;AACT,EAAE,EAAE;AACJ,EAAW;AACX,EAAE,OAAOA,uBAAkB,CAAC,cAAA,IAAkB;AAC9C,IAAI,MAAM,SAAA,GAAY,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;;AAErD,IAAI,MAAM,MAAA,GAASC,QAAI,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,OAAA,EAAS,CAAC;AACrD,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC;;AAEpC,IAAIC,kCAAuB,CAAC,cAAc,CAAC;;AAE3C,IAAI,OAAOC,cAAS;AACpB,MAAM;AACN,QAAQ,EAAE,EAAE,YAAY;AACxB,QAAQ,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,cAAA,EAAA,QAAA;AACA,UAAA,4BAAA,EAAA,KAAA,CAAA,KAAA;AACA,UAAA,kBAAA,EAAA,YAAA;AACA,UAAA,+BAAA,EAAA,KAAA,CAAA,QAAA,CAAA,MAAA;AACA,UAAA,+BAAA,EAAA,KAAA,CAAA,QAAA,CAAA,MAAA,CAAA,CAAA,GAAA,EAAA,OAAA,KAAA,GAAA,GAAA,OAAA,CAAA,QAAA,GAAA,CAAA,EAAA,CAAA,CAAA;AACA,UAAA,CAAAC,iCAAA,GAAA,eAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,4BAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,MAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,YAAA;AACA,QAAA,IAAA;AACA,UAAA,OAAA,MAAA,EAAA,EAAA;AACA,QAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,UAAAC,qBAAA,CAAA,CAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,KAAA,EAAA,IAAA,EAAA,4BAAA,EAAA,EAAA,CAAA;AACA,UAAA,MAAA,CAAA;AACA,QAAA,CAAA,SAAA;AACA,UAAA,SAAA,CAAAC,qBAAA,CAAA,MAAA,CAAA,CAAA;AACA,QAAA;AACA,MAAA,CAAA;AACA,KAAA;AACA,EAAA,CAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,8BAAA;AACA,EAAA,OAAA;AACA,EAAA,eAAA;AACA,EAAA;AACA,EAAA,IAAA,EAAA,OAAA,IAAA,OAAA,CAAA,IAAA,OAAA,OAAA,CAAA,KAAA,KAAA,UAAA,IAAAC,yBAAA,CAAA,OAAA,CAAA,KAAA,CAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,OAAA,CAAA,KAAA,GAAA,IAAA,KAAA,CAAA,OAAA,CAAA,KAAA,EAAA;AACA,IAAA,KAAA,CAAA,MAAA,EAAA,OAAA,EAAA,IAAA,EAAA;AACA,MAAA,MAAA,CAAA,KAAA,EAAA,GAAA,EAAA,GAAA,CAAA,GAAA,IAAA;AACA,MAAA,MAAA,OAAA,GAAAC,mCAAA,CAAA,GAAA,CAAA;AACA,MAAA,IAAA,CAAA,CAAA,CAAA,GAAA,OAAA;;AAEA,MAAA,MAAAC,SAAA,GAAAC,uBAAA,CAAA,eAAA,CAAA,GAAA,CAAA,EAAA,GAAA,CAAA;;AAEA,MAAA,OAAA,gBAAA,CAAA,KAAA,EAAAD,SAAA,EAAA,OAAA,EAAA,MAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA,CAAA;AACA,IAAA,CAAA;AACA,GAAA,CAAA;;AAEA,EAAAE,6BAAA,CAAA,OAAA,CAAA,KAAA,CAAA;AACA;;;;"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const core = require('@sentry/core');
|
|
4
|
+
const flush = require('../../flush.js');
|
|
5
|
+
const instrument = require('../../instrument.js');
|
|
6
|
+
const options = require('../../options.js');
|
|
7
|
+
const scopeUtils = require('../../scope-utils.js');
|
|
8
|
+
const sdk = require('../../sdk.js');
|
|
9
|
+
const instrumentContext = require('../../utils/instrumentContext.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Core scheduled handler logic - wraps execution with Sentry instrumentation.
|
|
13
|
+
*/
|
|
14
|
+
function wrapScheduledHandler(
|
|
15
|
+
controller,
|
|
16
|
+
options,
|
|
17
|
+
context,
|
|
18
|
+
fn,
|
|
19
|
+
) {
|
|
20
|
+
return core.withIsolationScope(isolationScope => {
|
|
21
|
+
const waitUntil = context.waitUntil.bind(context);
|
|
22
|
+
|
|
23
|
+
const client = sdk.init({ ...options, ctx: context });
|
|
24
|
+
isolationScope.setClient(client);
|
|
25
|
+
|
|
26
|
+
scopeUtils.addCloudResourceContext(isolationScope);
|
|
27
|
+
|
|
28
|
+
return core.startSpan(
|
|
29
|
+
{
|
|
30
|
+
op: 'faas.cron',
|
|
31
|
+
name: `Scheduled Cron ${controller.cron}`,
|
|
32
|
+
attributes: {
|
|
33
|
+
'faas.cron': controller.cron,
|
|
34
|
+
'faas.time': new Date(controller.scheduledTime).toISOString(),
|
|
35
|
+
'faas.trigger': 'timer',
|
|
36
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',
|
|
37
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
async () => {
|
|
41
|
+
try {
|
|
42
|
+
return await fn();
|
|
43
|
+
} catch (e) {
|
|
44
|
+
core.captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.scheduled' } });
|
|
45
|
+
throw e;
|
|
46
|
+
} finally {
|
|
47
|
+
waitUntil(flush.flushAndDispose(client));
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Instruments a scheduled handler for ExportedHandler (env/ctx come from args).
|
|
56
|
+
*/
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
+
function instrumentExportedHandlerScheduled(
|
|
59
|
+
handler,
|
|
60
|
+
optionsCallback,
|
|
61
|
+
) {
|
|
62
|
+
if (!('scheduled' in handler) || typeof handler.scheduled !== 'function' || instrument.isInstrumented(handler.scheduled)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
handler.scheduled = new Proxy(handler.scheduled, {
|
|
67
|
+
apply(target, thisArg, args) {
|
|
68
|
+
const [controller, env, ctx] = args;
|
|
69
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
70
|
+
args[2] = context;
|
|
71
|
+
|
|
72
|
+
const options$1 = options.getFinalOptions(optionsCallback(env), env);
|
|
73
|
+
|
|
74
|
+
return wrapScheduledHandler(controller, options$1, context, () => target.apply(thisArg, args));
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
instrument.markAsInstrumented(handler.scheduled);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
exports.instrumentExportedHandlerScheduled = instrumentExportedHandlerScheduled;
|
|
82
|
+
//# sourceMappingURL=instrumentScheduled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentScheduled.js","sources":["../../../../src/instrumentations/worker/instrumentScheduled.ts"],"sourcesContent":["import type { ExportedHandler, ScheduledController } from '@cloudflare/workers-types';\nimport {\n captureException,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n withIsolationScope,\n} from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { isInstrumented, markAsInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\n\n/**\n * Core scheduled handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapScheduledHandler(\n controller: ScheduledController,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.cron',\n name: `Scheduled Cron ${controller.cron}`,\n attributes: {\n 'faas.cron': controller.cron,\n 'faas.time': new Date(controller.scheduledTime).toISOString(),\n 'faas.trigger': 'timer',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.scheduled' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a scheduled handler for ExportedHandler (env/ctx come from args).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentExportedHandlerScheduled<T extends ExportedHandler<any, any, any>>(\n handler: T,\n optionsCallback: (env: Parameters<NonNullable<T['scheduled']>>[1]) => CloudflareOptions | undefined,\n): void {\n if (!('scheduled' in handler) || typeof handler.scheduled !== 'function' || isInstrumented(handler.scheduled)) {\n return;\n }\n\n handler.scheduled = new Proxy(handler.scheduled, {\n apply(target, thisArg, args: Parameters<NonNullable<T['scheduled']>>) {\n const [controller, env, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n return wrapScheduledHandler(controller, options, context, () => target.apply(thisArg, args));\n },\n });\n\n markAsInstrumented(handler.scheduled);\n}\n"],"names":["withIsolationScope","init","addCloudResourceContext","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","captureException","flushAndDispose","isInstrumented","instrumentContext","options","getFinalOptions","markAsInstrumented"],"mappings":";;;;;;;;;;AAgBA;AACA;AACA;AACA,SAAS,oBAAoB;AAC7B,EAAE,UAAU;AACZ,EAAE,OAAO;AACT,EAAE,OAAO;AACT,EAAE,EAAE;AACJ,EAAW;AACX,EAAE,OAAOA,uBAAkB,CAAC,cAAA,IAAkB;AAC9C,IAAI,MAAM,SAAA,GAAY,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;;AAErD,IAAI,MAAM,MAAA,GAASC,QAAI,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,OAAA,EAAS,CAAC;AACrD,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC;;AAEpC,IAAIC,kCAAuB,CAAC,cAAc,CAAC;;AAE3C,IAAI,OAAOC,cAAS;AACpB,MAAM;AACN,QAAQ,EAAE,EAAE,WAAW;AACvB,QAAQ,IAAI,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC,IAAI,CAAC,CAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,WAAA,EAAA,UAAA,CAAA,IAAA;AACA,UAAA,WAAA,EAAA,IAAA,IAAA,CAAA,UAAA,CAAA,aAAA,CAAA,CAAA,WAAA,EAAA;AACA,UAAA,cAAA,EAAA,OAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,gCAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,MAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,YAAA;AACA,QAAA,IAAA;AACA,UAAA,OAAA,MAAA,EAAA,EAAA;AACA,QAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,UAAAC,qBAAA,CAAA,CAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,KAAA,EAAA,IAAA,EAAA,gCAAA,EAAA,EAAA,CAAA;AACA,UAAA,MAAA,CAAA;AACA,QAAA,CAAA,SAAA;AACA,UAAA,SAAA,CAAAC,qBAAA,CAAA,MAAA,CAAA,CAAA;AACA,QAAA;AACA,MAAA,CAAA;AACA,KAAA;AACA,EAAA,CAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,kCAAA;AACA,EAAA,OAAA;AACA,EAAA,eAAA;AACA,EAAA;AACA,EAAA,IAAA,EAAA,WAAA,IAAA,OAAA,CAAA,IAAA,OAAA,OAAA,CAAA,SAAA,KAAA,UAAA,IAAAC,yBAAA,CAAA,OAAA,CAAA,SAAA,CAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,OAAA,CAAA,SAAA,GAAA,IAAA,KAAA,CAAA,OAAA,CAAA,SAAA,EAAA;AACA,IAAA,KAAA,CAAA,MAAA,EAAA,OAAA,EAAA,IAAA,EAAA;AACA,MAAA,MAAA,CAAA,UAAA,EAAA,GAAA,EAAA,GAAA,CAAA,GAAA,IAAA;AACA,MAAA,MAAA,OAAA,GAAAC,mCAAA,CAAA,GAAA,CAAA;AACA,MAAA,IAAA,CAAA,CAAA,CAAA,GAAA,OAAA;;AAEA,MAAA,MAAAC,SAAA,GAAAC,uBAAA,CAAA,eAAA,CAAA,GAAA,CAAA,EAAA,GAAA,CAAA;;AAEA,MAAA,OAAA,oBAAA,CAAA,UAAA,EAAAD,SAAA,EAAA,OAAA,EAAA,MAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA,CAAA;AACA,IAAA,CAAA;AACA,GAAA,CAAA;;AAEA,EAAAE,6BAAA,CAAA,OAAA,CAAA,SAAA,CAAA;AACA;;;;"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const core = require('@sentry/core');
|
|
4
|
+
const flush = require('../../flush.js');
|
|
5
|
+
const instrument = require('../../instrument.js');
|
|
6
|
+
const options = require('../../options.js');
|
|
7
|
+
const scopeUtils = require('../../scope-utils.js');
|
|
8
|
+
const sdk = require('../../sdk.js');
|
|
9
|
+
const instrumentContext = require('../../utils/instrumentContext.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Core tail handler logic - wraps execution with Sentry instrumentation.
|
|
13
|
+
* Note: tail handlers don't create spans, just error capture.
|
|
14
|
+
*/
|
|
15
|
+
function wrapTailHandler(options, context, fn) {
|
|
16
|
+
return core.withIsolationScope(async isolationScope => {
|
|
17
|
+
const waitUntil = context.waitUntil.bind(context);
|
|
18
|
+
|
|
19
|
+
const client = sdk.init({ ...options, ctx: context });
|
|
20
|
+
isolationScope.setClient(client);
|
|
21
|
+
|
|
22
|
+
scopeUtils.addCloudResourceContext(isolationScope);
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
return await fn();
|
|
26
|
+
} catch (e) {
|
|
27
|
+
core.captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.tail' } });
|
|
28
|
+
throw e;
|
|
29
|
+
} finally {
|
|
30
|
+
waitUntil(flush.flushAndDispose(client));
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Instruments a tail handler for ExportedHandler (env/ctx come from args).
|
|
37
|
+
*/
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
+
function instrumentExportedHandlerTail(
|
|
40
|
+
handler,
|
|
41
|
+
optionsCallback,
|
|
42
|
+
) {
|
|
43
|
+
if (!('tail' in handler) || typeof handler.tail !== 'function' || instrument.isInstrumented(handler.tail)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
handler.tail = new Proxy(handler.tail, {
|
|
48
|
+
apply(target, thisArg, args) {
|
|
49
|
+
const [, env, ctx] = args;
|
|
50
|
+
const context = instrumentContext.instrumentContext(ctx);
|
|
51
|
+
args[2] = context;
|
|
52
|
+
|
|
53
|
+
const options$1 = options.getFinalOptions(optionsCallback(env), env);
|
|
54
|
+
|
|
55
|
+
return wrapTailHandler(options$1, context, () => target.apply(thisArg, args));
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
instrument.markAsInstrumented(handler.tail);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
exports.instrumentExportedHandlerTail = instrumentExportedHandlerTail;
|
|
63
|
+
//# sourceMappingURL=instrumentTail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentTail.js","sources":["../../../../src/instrumentations/worker/instrumentTail.ts"],"sourcesContent":["import type { ExportedHandler } from '@cloudflare/workers-types';\nimport { captureException, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { isInstrumented, markAsInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\n\n/**\n * Core tail handler logic - wraps execution with Sentry instrumentation.\n * Note: tail handlers don't create spans, just error capture.\n */\nfunction wrapTailHandler(options: CloudflareOptions, context: ExecutionContext, fn: () => unknown): unknown {\n return withIsolationScope(async isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.tail' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n });\n}\n\n/**\n * Instruments a tail handler for ExportedHandler (env/ctx come from args).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentExportedHandlerTail<T extends ExportedHandler<any, any, any>>(\n handler: T,\n optionsCallback: (env: Parameters<NonNullable<T['tail']>>[1]) => CloudflareOptions | undefined,\n): void {\n if (!('tail' in handler) || typeof handler.tail !== 'function' || isInstrumented(handler.tail)) {\n return;\n }\n\n handler.tail = new Proxy(handler.tail, {\n apply(target, thisArg, args: Parameters<NonNullable<T['tail']>>) {\n const [, env, ctx] = args;\n const context = instrumentContext(ctx);\n args[2] = context;\n\n const options = getFinalOptions(optionsCallback(env), env);\n\n return wrapTailHandler(options, context, () => target.apply(thisArg, args));\n },\n });\n\n markAsInstrumented(handler.tail);\n}\n"],"names":["withIsolationScope","init","addCloudResourceContext","captureException","flushAndDispose","isInstrumented","instrumentContext","options","getFinalOptions","markAsInstrumented"],"mappings":";;;;;;;;;;AAUA;AACA;AACA;AACA;AACA,SAAS,eAAe,CAAC,OAAO,EAAqB,OAAO,EAAoB,EAAE,EAA0B;AAC5G,EAAE,OAAOA,uBAAkB,CAAC,MAAM,kBAAkB;AACpD,IAAI,MAAM,SAAA,GAAY,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;;AAErD,IAAI,MAAM,MAAA,GAASC,QAAI,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,OAAA,EAAS,CAAC;AACrD,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC;;AAEpC,IAAIC,kCAAuB,CAAC,cAAc,CAAC;;AAE3C,IAAI,IAAI;AACR,MAAM,OAAO,MAAM,EAAE,EAAE;AACvB,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB,MAAMC,qBAAgB,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,2BAAA,EAA4B,EAAG,CAAC;AAC/F,MAAM,MAAM,CAAC;AACb,IAAI,UAAU;AACd,MAAM,SAAS,CAACC,qBAAe,CAAC,MAAM,CAAC,CAAC;AACxC,IAAI;AACJ,EAAE,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACO,SAAS,6BAA6B;AAC7C,EAAE,OAAO;AACT,EAAE,eAAe;AACjB,EAAQ;AACR,EAAE,IAAI,EAAE,UAAU,OAAO,CAAA,IAAK,OAAO,OAAO,CAAC,IAAA,KAAS,cAAcC,yBAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAClG,IAAI;AACJ,EAAE;;AAEF,EAAE,OAAO,CAAC,IAAA,GAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;AACzC,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAsC;AACrE,MAAM,MAAM,GAAG,GAAG,EAAE,GAAG,CAAA,GAAI,IAAI;AAC/B,MAAM,MAAM,OAAA,GAAUC,mCAAiB,CAAC,GAAG,CAAC;AAC5C,MAAM,IAAI,CAAC,CAAC,CAAA,GAAI,OAAO;;AAEvB,MAAM,MAAMC,SAAA,GAAUC,uBAAe,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;;AAEhE,MAAM,OAAO,eAAe,CAACD,SAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACjF,IAAI,CAAC;AACL,GAAG,CAAC;;AAEJ,EAAEE,6BAAkB,CAAC,OAAO,CAAC,IAAI,CAAC;AAClC;;;;"}
|
package/build/cjs/request.js
CHANGED
|
@@ -133,7 +133,7 @@ function wrapRequestHandler(
|
|
|
133
133
|
statusText: res.statusText,
|
|
134
134
|
headers: res.headers,
|
|
135
135
|
});
|
|
136
|
-
} catch (
|
|
136
|
+
} catch (_e) {
|
|
137
137
|
// tee() failed (e.g stream already locked) - fall back to non-streaming handling
|
|
138
138
|
span.end();
|
|
139
139
|
waitUntil?.(flush.flushAndDispose(client));
|
package/build/cjs/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sources":["../../src/request.ts"],"sourcesContent":["import type { ExecutionContext, IncomingRequestCfProperties } from '@cloudflare/workers-types';\nimport {\n captureException,\n continueTrace,\n getClient,\n getHttpSpanDetailsFromUrlObject,\n httpHeadersToSpanAttributes,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n setHttpStatus,\n startSpanManual,\n winterCGHeadersToDict,\n withIsolationScope,\n} from '@sentry/core';\nimport type { CloudflareOptions } from './client';\nimport { flushAndDispose } from './flush';\nimport { addCloudResourceContext, addCultureContext, addRequest } from './scope-utils';\nimport { init } from './sdk';\nimport { classifyResponseStreaming } from './utils/streaming';\n\ninterface RequestHandlerWrapperOptions {\n options: CloudflareOptions;\n request: Request<unknown, IncomingRequestCfProperties<unknown>>;\n context: ExecutionContext;\n /**\n * If true, errors will be captured, rethrown and sent to Sentry.\n * Otherwise, errors are rethrown but not captured.\n *\n * You most likely don't want to set this to `false`, if you use `wrapRequestHandler` directly.\n * This is primarily meant as an escape hatch for higher-level SDKs relying on additional error\n * capturing mechanisms where this wrapper captures errors too early or too generally.\n *\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Wraps a cloudflare request handler in Sentry instrumentation\n */\nexport function wrapRequestHandler(\n wrapperOptions: RequestHandlerWrapperOptions,\n handler: (...args: unknown[]) => Response | Promise<Response>,\n): Promise<Response> {\n return withIsolationScope(async isolationScope => {\n const { options, request, captureErrors = true } = wrapperOptions;\n\n // In certain situations, the passed context can become undefined.\n // For example, for Astro while prerendering pages at build time.\n // see: https://github.com/getsentry/sentry-javascript/issues/13217\n const context = wrapperOptions.context as ExecutionContext | undefined;\n\n const waitUntil = context?.waitUntil?.bind?.(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n const urlObject = parseStringToURLObject(request.url);\n const [name, attributes] = getHttpSpanDetailsFromUrlObject(urlObject, 'server', 'auto.http.cloudflare', request);\n\n const contentLength = request.headers.get('content-length');\n if (contentLength) {\n attributes['http.request.body.size'] = parseInt(contentLength, 10);\n }\n\n const userAgentHeader = request.headers.get('user-agent');\n if (userAgentHeader) {\n attributes['user_agent.original'] = userAgentHeader;\n }\n\n Object.assign(\n attributes,\n httpHeadersToSpanAttributes(\n winterCGHeadersToDict(request.headers),\n getClient()?.getOptions().sendDefaultPii ?? false,\n ),\n );\n\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] = 'http.server';\n\n addCloudResourceContext(isolationScope);\n addRequest(isolationScope, request);\n if (request.cf) {\n addCultureContext(isolationScope, request.cf);\n attributes['network.protocol.name'] = request.cf.httpProtocol;\n }\n\n // Do not capture spans for OPTIONS and HEAD requests\n if (request.method === 'OPTIONS' || request.method === 'HEAD') {\n try {\n return await handler();\n } catch (e) {\n if (captureErrors) {\n captureException(e, { mechanism: { handled: false, type: 'auto.http.cloudflare' } });\n }\n throw e;\n } finally {\n waitUntil?.(flushAndDispose(client));\n }\n }\n\n return continueTrace(\n { sentryTrace: request.headers.get('sentry-trace') || '', baggage: request.headers.get('baggage') },\n () => {\n // Note: This span will not have a duration unless I/O happens in the handler. This is\n // because of how the cloudflare workers runtime works.\n // See: https://developers.cloudflare.com/workers/runtime-apis/performance/\n\n // Use startSpanManual to control when span ends (needed for streaming responses)\n return startSpanManual({ name, attributes }, async span => {\n let res: Response;\n\n try {\n res = await handler();\n setHttpStatus(span, res.status);\n\n // After the handler runs, the span name might have been updated by nested instrumentation\n // (e.g., Remix parameterizing routes). The span should already have the correct name\n // from that instrumentation, so we don't need to do anything here.\n } catch (e) {\n span.end();\n if (captureErrors) {\n captureException(e, { mechanism: { handled: false, type: 'auto.http.cloudflare' } });\n }\n waitUntil?.(flushAndDispose(client));\n throw e;\n }\n\n // Classify response to detect actual streaming\n const classification = classifyResponseStreaming(res);\n\n if (classification.isStreaming && res.body) {\n // Streaming response detected - monitor consumption to keep span alive\n try {\n const [clientStream, monitorStream] = res.body.tee();\n\n // Monitor stream consumption and end span when complete\n const streamMonitor = (async () => {\n const reader = monitorStream.getReader();\n\n try {\n let done = false;\n while (!done) {\n const result = await reader.read();\n done = result.done;\n }\n } catch {\n // Stream error or cancellation - will end span in finally\n } finally {\n reader.releaseLock();\n span.end();\n waitUntil?.(flushAndDispose(client));\n }\n })();\n\n // Keep worker alive until stream monitoring completes (otherwise span won't end)\n waitUntil?.(streamMonitor);\n\n // Return response with client stream\n return new Response(clientStream, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n } catch (e) {\n // tee() failed (e.g stream already locked) - fall back to non-streaming handling\n span.end();\n waitUntil?.(flushAndDispose(client));\n return res;\n }\n }\n\n // Non-streaming response - end span immediately and return original\n span.end();\n\n // Don't dispose for protocol upgrades (101 Switching Protocols) - the connection stays alive.\n // This includes WebSocket upgrades where webSocketMessage/webSocketClose handlers\n // will still be called and may need the client to capture errors.\n if (res.status === 101) {\n waitUntil?.(client?.flush(2000));\n } else {\n waitUntil?.(flushAndDispose(client));\n }\n return res;\n });\n },\n );\n });\n}\n"],"names":["withIsolationScope","init","parseStringToURLObject","getHttpSpanDetailsFromUrlObject","httpHeadersToSpanAttributes","winterCGHeadersToDict","getClient","SEMANTIC_ATTRIBUTE_SENTRY_OP","addCloudResourceContext","addRequest","addCultureContext","captureException","flushAndDispose","continueTrace","startSpanManual","setHttpStatus","classifyResponseStreaming"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"request.js","sources":["../../src/request.ts"],"sourcesContent":["import type { ExecutionContext, IncomingRequestCfProperties } from '@cloudflare/workers-types';\nimport {\n captureException,\n continueTrace,\n getClient,\n getHttpSpanDetailsFromUrlObject,\n httpHeadersToSpanAttributes,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n setHttpStatus,\n startSpanManual,\n winterCGHeadersToDict,\n withIsolationScope,\n} from '@sentry/core';\nimport type { CloudflareOptions } from './client';\nimport { flushAndDispose } from './flush';\nimport { addCloudResourceContext, addCultureContext, addRequest } from './scope-utils';\nimport { init } from './sdk';\nimport { classifyResponseStreaming } from './utils/streaming';\n\ninterface RequestHandlerWrapperOptions {\n options: CloudflareOptions;\n request: Request<unknown, IncomingRequestCfProperties<unknown>>;\n context: ExecutionContext;\n /**\n * If true, errors will be captured, rethrown and sent to Sentry.\n * Otherwise, errors are rethrown but not captured.\n *\n * You most likely don't want to set this to `false`, if you use `wrapRequestHandler` directly.\n * This is primarily meant as an escape hatch for higher-level SDKs relying on additional error\n * capturing mechanisms where this wrapper captures errors too early or too generally.\n *\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Wraps a cloudflare request handler in Sentry instrumentation\n */\nexport function wrapRequestHandler(\n wrapperOptions: RequestHandlerWrapperOptions,\n handler: (...args: unknown[]) => Response | Promise<Response>,\n): Promise<Response> {\n return withIsolationScope(async isolationScope => {\n const { options, request, captureErrors = true } = wrapperOptions;\n\n // In certain situations, the passed context can become undefined.\n // For example, for Astro while prerendering pages at build time.\n // see: https://github.com/getsentry/sentry-javascript/issues/13217\n const context = wrapperOptions.context as ExecutionContext | undefined;\n\n const waitUntil = context?.waitUntil?.bind?.(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n const urlObject = parseStringToURLObject(request.url);\n const [name, attributes] = getHttpSpanDetailsFromUrlObject(urlObject, 'server', 'auto.http.cloudflare', request);\n\n const contentLength = request.headers.get('content-length');\n if (contentLength) {\n attributes['http.request.body.size'] = parseInt(contentLength, 10);\n }\n\n const userAgentHeader = request.headers.get('user-agent');\n if (userAgentHeader) {\n attributes['user_agent.original'] = userAgentHeader;\n }\n\n Object.assign(\n attributes,\n httpHeadersToSpanAttributes(\n winterCGHeadersToDict(request.headers),\n getClient()?.getOptions().sendDefaultPii ?? false,\n ),\n );\n\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] = 'http.server';\n\n addCloudResourceContext(isolationScope);\n addRequest(isolationScope, request);\n if (request.cf) {\n addCultureContext(isolationScope, request.cf);\n attributes['network.protocol.name'] = request.cf.httpProtocol;\n }\n\n // Do not capture spans for OPTIONS and HEAD requests\n if (request.method === 'OPTIONS' || request.method === 'HEAD') {\n try {\n return await handler();\n } catch (e) {\n if (captureErrors) {\n captureException(e, { mechanism: { handled: false, type: 'auto.http.cloudflare' } });\n }\n throw e;\n } finally {\n waitUntil?.(flushAndDispose(client));\n }\n }\n\n return continueTrace(\n { sentryTrace: request.headers.get('sentry-trace') || '', baggage: request.headers.get('baggage') },\n () => {\n // Note: This span will not have a duration unless I/O happens in the handler. This is\n // because of how the cloudflare workers runtime works.\n // See: https://developers.cloudflare.com/workers/runtime-apis/performance/\n\n // Use startSpanManual to control when span ends (needed for streaming responses)\n return startSpanManual({ name, attributes }, async span => {\n let res: Response;\n\n try {\n res = await handler();\n setHttpStatus(span, res.status);\n\n // After the handler runs, the span name might have been updated by nested instrumentation\n // (e.g., Remix parameterizing routes). The span should already have the correct name\n // from that instrumentation, so we don't need to do anything here.\n } catch (e) {\n span.end();\n if (captureErrors) {\n captureException(e, { mechanism: { handled: false, type: 'auto.http.cloudflare' } });\n }\n waitUntil?.(flushAndDispose(client));\n throw e;\n }\n\n // Classify response to detect actual streaming\n const classification = classifyResponseStreaming(res);\n\n if (classification.isStreaming && res.body) {\n // Streaming response detected - monitor consumption to keep span alive\n try {\n const [clientStream, monitorStream] = res.body.tee();\n\n // Monitor stream consumption and end span when complete\n const streamMonitor = (async () => {\n const reader = monitorStream.getReader();\n\n try {\n let done = false;\n while (!done) {\n const result = await reader.read();\n done = result.done;\n }\n } catch {\n // Stream error or cancellation - will end span in finally\n } finally {\n reader.releaseLock();\n span.end();\n waitUntil?.(flushAndDispose(client));\n }\n })();\n\n // Keep worker alive until stream monitoring completes (otherwise span won't end)\n waitUntil?.(streamMonitor);\n\n // Return response with client stream\n return new Response(clientStream, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n } catch (_e) {\n // tee() failed (e.g stream already locked) - fall back to non-streaming handling\n span.end();\n waitUntil?.(flushAndDispose(client));\n return res;\n }\n }\n\n // Non-streaming response - end span immediately and return original\n span.end();\n\n // Don't dispose for protocol upgrades (101 Switching Protocols) - the connection stays alive.\n // This includes WebSocket upgrades where webSocketMessage/webSocketClose handlers\n // will still be called and may need the client to capture errors.\n if (res.status === 101) {\n waitUntil?.(client?.flush(2000));\n } else {\n waitUntil?.(flushAndDispose(client));\n }\n return res;\n });\n },\n );\n });\n}\n"],"names":["withIsolationScope","init","parseStringToURLObject","getHttpSpanDetailsFromUrlObject","httpHeadersToSpanAttributes","winterCGHeadersToDict","getClient","SEMANTIC_ATTRIBUTE_SENTRY_OP","addCloudResourceContext","addRequest","addCultureContext","captureException","flushAndDispose","continueTrace","startSpanManual","setHttpStatus","classifyResponseStreaming"],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const async = require('./async.js');
|
|
4
|
+
const instrument = require('./instrument.js');
|
|
5
|
+
const hono = require('./integrations/hono.js');
|
|
6
|
+
const instrumentEmail = require('./instrumentations/worker/instrumentEmail.js');
|
|
7
|
+
const instrumentFetch = require('./instrumentations/worker/instrumentFetch.js');
|
|
8
|
+
const instrumentQueue = require('./instrumentations/worker/instrumentQueue.js');
|
|
9
|
+
const instrumentScheduled = require('./instrumentations/worker/instrumentScheduled.js');
|
|
10
|
+
const instrumentTail = require('./instrumentations/worker/instrumentTail.js');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Wrapper for Cloudflare handlers.
|
|
14
|
+
*
|
|
15
|
+
* Initializes the SDK and wraps the handler with Sentry instrumentation.
|
|
16
|
+
*
|
|
17
|
+
* Automatically instruments the `fetch` method of the handler.
|
|
18
|
+
*
|
|
19
|
+
* @param optionsCallback Function that returns the options for the SDK initialization.
|
|
20
|
+
* @param handler {ExportedHandler} The handler to wrap.
|
|
21
|
+
* @returns The wrapped handler.
|
|
22
|
+
*/
|
|
23
|
+
function withSentry
|
|
24
|
+
|
|
25
|
+
(optionsCallback, handler) {
|
|
26
|
+
async.setAsyncLocalStorageAsyncContextStrategy();
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
instrumentFetch.instrumentExportedHandlerFetch(handler, optionsCallback);
|
|
30
|
+
instrumentHonoErrorHandler(handler);
|
|
31
|
+
instrumentScheduled.instrumentExportedHandlerScheduled(handler, optionsCallback);
|
|
32
|
+
instrumentEmail.instrumentExportedHandlerEmail(handler, optionsCallback);
|
|
33
|
+
instrumentQueue.instrumentExportedHandlerQueue(handler, optionsCallback);
|
|
34
|
+
instrumentTail.instrumentExportedHandlerTail(handler, optionsCallback);
|
|
35
|
+
// This is here because Miniflare sometimes cannot get instrumented
|
|
36
|
+
} catch {
|
|
37
|
+
// Do not console anything here, we don't want to spam the console with errors
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return handler;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
+
function instrumentHonoErrorHandler(handler) {
|
|
45
|
+
if (
|
|
46
|
+
'onError' in handler &&
|
|
47
|
+
'errorHandler' in handler &&
|
|
48
|
+
typeof handler.errorHandler === 'function' &&
|
|
49
|
+
!instrument.isInstrumented(handler.errorHandler)
|
|
50
|
+
) {
|
|
51
|
+
handler.errorHandler = new Proxy(handler.errorHandler, {
|
|
52
|
+
apply(target, thisArg, args) {
|
|
53
|
+
const [err, context] = args;
|
|
54
|
+
|
|
55
|
+
hono.getHonoIntegration()?.handleHonoException(err, context);
|
|
56
|
+
|
|
57
|
+
return Reflect.apply(target, thisArg, args);
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
instrument.markAsInstrumented(handler.errorHandler);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.withSentry = withSentry;
|
|
66
|
+
//# sourceMappingURL=withSentry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withSentry.js","sources":["../../src/withSentry.ts"],"sourcesContent":["import { setAsyncLocalStorageAsyncContextStrategy } from './async';\nimport type { CloudflareOptions } from './client';\nimport { isInstrumented, markAsInstrumented } from './instrument';\nimport { getHonoIntegration } from './integrations/hono';\nimport { instrumentExportedHandlerEmail } from './instrumentations/worker/instrumentEmail';\nimport { instrumentExportedHandlerFetch } from './instrumentations/worker/instrumentFetch';\nimport { instrumentExportedHandlerQueue } from './instrumentations/worker/instrumentQueue';\nimport { instrumentExportedHandlerScheduled } from './instrumentations/worker/instrumentScheduled';\nimport { instrumentExportedHandlerTail } from './instrumentations/worker/instrumentTail';\n\n/**\n * Wrapper for Cloudflare handlers.\n *\n * Initializes the SDK and wraps the handler with Sentry instrumentation.\n *\n * Automatically instruments the `fetch` method of the handler.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param handler {ExportedHandler} The handler to wrap.\n * @returns The wrapped handler.\n */\nexport function withSentry<\n Env = unknown,\n QueueHandlerMessage = unknown,\n CfHostMetadata = unknown,\n T extends ExportedHandler<Env, QueueHandlerMessage, CfHostMetadata> = ExportedHandler<\n Env,\n QueueHandlerMessage,\n CfHostMetadata\n >,\n>(optionsCallback: (env: Env) => CloudflareOptions | undefined, handler: T): T {\n setAsyncLocalStorageAsyncContextStrategy();\n\n try {\n instrumentExportedHandlerFetch(handler, optionsCallback);\n instrumentHonoErrorHandler(handler);\n instrumentExportedHandlerScheduled(handler, optionsCallback);\n instrumentExportedHandlerEmail(handler, optionsCallback);\n instrumentExportedHandlerQueue(handler, optionsCallback);\n instrumentExportedHandlerTail(handler, optionsCallback);\n // This is here because Miniflare sometimes cannot get instrumented\n } catch {\n // Do not console anything here, we don't want to spam the console with errors\n }\n\n return handler;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction instrumentHonoErrorHandler<T extends ExportedHandler<any, any, any>>(handler: T): void {\n if (\n 'onError' in handler &&\n 'errorHandler' in handler &&\n typeof handler.errorHandler === 'function' &&\n !isInstrumented(handler.errorHandler)\n ) {\n handler.errorHandler = new Proxy(handler.errorHandler, {\n apply(target, thisArg, args) {\n const [err, context] = args;\n\n getHonoIntegration()?.handleHonoException(err, context);\n\n return Reflect.apply(target, thisArg, args);\n },\n });\n\n markAsInstrumented(handler.errorHandler);\n }\n}\n"],"names":["setAsyncLocalStorageAsyncContextStrategy","instrumentExportedHandlerFetch","instrumentExportedHandlerScheduled","instrumentExportedHandlerEmail","instrumentExportedHandlerQueue","instrumentExportedHandlerTail","isInstrumented","getHonoIntegration","markAsInstrumented"],"mappings":";;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS;;AAShB,CAAE,eAAe,EAA+C,OAAO,EAAQ;AAC/E,EAAEA,8CAAwC,EAAE;;AAE5C,EAAE,IAAI;AACN,IAAIC,8CAA8B,CAAC,OAAO,EAAE,eAAe,CAAC;AAC5D,IAAI,0BAA0B,CAAC,OAAO,CAAC;AACvC,IAAIC,sDAAkC,CAAC,OAAO,EAAE,eAAe,CAAC;AAChE,IAAIC,8CAA8B,CAAC,OAAO,EAAE,eAAe,CAAC;AAC5D,IAAIC,8CAA8B,CAAC,OAAO,EAAE,eAAe,CAAC;AAC5D,IAAIC,4CAA6B,CAAC,OAAO,EAAE,eAAe,CAAC;AAC3D;AACA,EAAE,EAAE,MAAM;AACV;AACA,EAAE;;AAEF,EAAE,OAAO,OAAO;AAChB;;AAEA;AACA,SAAS,0BAA0B,CAA2C,OAAO,EAAW;AAChG,EAAE;AACF,IAAI,SAAA,IAAa,OAAA;AACjB,IAAI,cAAA,IAAkB,OAAA;AACtB,IAAI,OAAO,OAAO,CAAC,YAAA,KAAiB,UAAA;AACpC,IAAI,CAACC,yBAAc,CAAC,OAAO,CAAC,YAAY;AACxC,IAAI;AACJ,IAAI,OAAO,CAAC,YAAA,GAAe,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE;AAC3D,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;AACnC,QAAQ,MAAM,CAAC,GAAG,EAAE,OAAO,CAAA,GAAI,IAAI;;AAEnC,QAAQC,uBAAkB,EAAE,EAAE,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC;;AAE/D,QAAQ,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AACnD,MAAM,CAAC;AACP,KAAK,CAAC;;AAEN,IAAIC,6BAAkB,CAAC,OAAO,CAAC,YAAY,CAAC;AAC5C,EAAE;AACF;;;;"}
|
|
@@ -44,13 +44,17 @@ function wrapMethodWithSentry(
|
|
|
44
44
|
|
|
45
45
|
const waitUntil = context?.waitUntil?.bind?.(context);
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
if (
|
|
47
|
+
let currentClient = scope.getClient();
|
|
48
|
+
// Check if client exists AND is still usable (transport not disposed)
|
|
49
|
+
// This handles the case where a previous handler disposed the client
|
|
50
|
+
// but the scope still holds a reference to it (e.g., alarm handlers in Durable Objects)
|
|
51
|
+
if (!currentClient?.getTransport()) {
|
|
49
52
|
const client = sdk.init({ ...wrapperOptions.options, ctx: context });
|
|
50
53
|
scope.setClient(client);
|
|
54
|
+
currentClient = client;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
const clientToDispose = currentClient
|
|
57
|
+
const clientToDispose = currentClient;
|
|
54
58
|
|
|
55
59
|
if (!wrapperOptions.spanName) {
|
|
56
60
|
try {
|