@sentry/cloudflare 10.32.1 → 10.34.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.
@@ -60,6 +60,7 @@ const _fetchIntegration = ((options = {}) => {
60
60
  setupOnce() {
61
61
  core.addFetchInstrumentationHandler(handlerData => {
62
62
  const client = core.getClient();
63
+ const { propagateTraceparent } = client?.getOptions() || {};
63
64
  if (!client || !HAS_CLIENT_MAP.get(client)) {
64
65
  return;
65
66
  }
@@ -70,6 +71,7 @@ const _fetchIntegration = ((options = {}) => {
70
71
 
71
72
  core.instrumentFetchRequest(handlerData, _shouldCreateSpan, _shouldAttachTraceData, spans, {
72
73
  spanOrigin: 'auto.http.fetch',
74
+ propagateTraceparent,
73
75
  });
74
76
 
75
77
  if (breadcrumbs) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sources":["../../../src/integrations/fetch.ts"],"sourcesContent":["import type {\n Client,\n FetchBreadcrumbData,\n FetchBreadcrumbHint,\n HandlerDataFetch,\n IntegrationFn,\n Span,\n} from '@sentry/core';\nimport {\n addBreadcrumb,\n addFetchInstrumentationHandler,\n defineIntegration,\n getBreadcrumbLogLevelFromHttpStatusCode,\n getClient,\n instrumentFetchRequest,\n isSentryRequestUrl,\n LRUMap,\n stringMatchesSomePattern,\n} from '@sentry/core';\n\nconst INTEGRATION_NAME = 'Fetch';\n\nconst HAS_CLIENT_MAP = new WeakMap<Client, boolean>();\n\nexport interface Options {\n /**\n * Whether breadcrumbs should be recorded for requests\n * Defaults to true\n */\n breadcrumbs: boolean;\n\n /**\n * Function determining whether or not to create spans to track outgoing requests to the given URL.\n * By default, spans will be created for all outgoing requests.\n */\n shouldCreateSpanForRequest?: (url: string) => boolean;\n}\n\nconst _fetchIntegration = ((options: Partial<Options> = {}) => {\n const breadcrumbs = options.breadcrumbs === undefined ? true : options.breadcrumbs;\n const shouldCreateSpanForRequest = options.shouldCreateSpanForRequest;\n\n const _createSpanUrlMap = new LRUMap<string, boolean>(100);\n const _headersUrlMap = new LRUMap<string, boolean>(100);\n\n const spans: Record<string, Span> = {};\n\n /** Decides whether to attach trace data to the outgoing fetch request */\n function _shouldAttachTraceData(url: string): boolean {\n const client = getClient();\n\n if (!client) {\n return false;\n }\n\n const clientOptions = client.getOptions();\n\n if (clientOptions.tracePropagationTargets === undefined) {\n return true;\n }\n\n const cachedDecision = _headersUrlMap.get(url);\n if (cachedDecision !== undefined) {\n return cachedDecision;\n }\n\n const decision = stringMatchesSomePattern(url, clientOptions.tracePropagationTargets);\n _headersUrlMap.set(url, decision);\n return decision;\n }\n\n /** Helper that wraps shouldCreateSpanForRequest option */\n function _shouldCreateSpan(url: string): boolean {\n if (shouldCreateSpanForRequest === undefined) {\n return true;\n }\n\n const cachedDecision = _createSpanUrlMap.get(url);\n if (cachedDecision !== undefined) {\n return cachedDecision;\n }\n\n const decision = shouldCreateSpanForRequest(url);\n _createSpanUrlMap.set(url, decision);\n return decision;\n }\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n addFetchInstrumentationHandler(handlerData => {\n const client = getClient();\n if (!client || !HAS_CLIENT_MAP.get(client)) {\n return;\n }\n\n if (isSentryRequestUrl(handlerData.fetchData.url, client)) {\n return;\n }\n\n instrumentFetchRequest(handlerData, _shouldCreateSpan, _shouldAttachTraceData, spans, {\n spanOrigin: 'auto.http.fetch',\n });\n\n if (breadcrumbs) {\n createBreadcrumb(handlerData);\n }\n }, true);\n },\n setup(client) {\n HAS_CLIENT_MAP.set(client, true);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Creates spans and attaches tracing headers to fetch requests.\n */\nexport const fetchIntegration = defineIntegration(_fetchIntegration);\n\nfunction createBreadcrumb(handlerData: HandlerDataFetch): void {\n const { startTimestamp, endTimestamp } = handlerData;\n\n // We only capture complete fetch requests\n if (!endTimestamp) {\n return;\n }\n\n const breadcrumbData: FetchBreadcrumbData = {\n method: handlerData.fetchData.method,\n url: handlerData.fetchData.url,\n };\n\n if (handlerData.error) {\n const hint: FetchBreadcrumbHint = {\n data: handlerData.error,\n input: handlerData.args,\n startTimestamp,\n endTimestamp,\n };\n\n addBreadcrumb(\n {\n category: 'fetch',\n data: breadcrumbData,\n level: 'error',\n type: 'http',\n },\n hint,\n );\n } else {\n const response = handlerData.response as Response | undefined;\n\n breadcrumbData.request_body_size = handlerData.fetchData.request_body_size;\n breadcrumbData.response_body_size = handlerData.fetchData.response_body_size;\n breadcrumbData.status_code = response?.status;\n\n const hint: FetchBreadcrumbHint = {\n input: handlerData.args,\n response,\n startTimestamp,\n endTimestamp,\n };\n const level = getBreadcrumbLogLevelFromHttpStatusCode(breadcrumbData.status_code);\n\n addBreadcrumb(\n {\n category: 'fetch',\n data: breadcrumbData,\n type: 'http',\n level,\n },\n hint,\n );\n }\n}\n"],"names":["LRUMap","getClient","stringMatchesSomePattern","addFetchInstrumentationHandler","isSentryRequestUrl","instrumentFetchRequest","defineIntegration","addBreadcrumb","getBreadcrumbLogLevelFromHttpStatusCode"],"mappings":"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"}
1
+ {"version":3,"file":"fetch.js","sources":["../../../src/integrations/fetch.ts"],"sourcesContent":["import type {\n Client,\n FetchBreadcrumbData,\n FetchBreadcrumbHint,\n HandlerDataFetch,\n IntegrationFn,\n Span,\n} from '@sentry/core';\nimport {\n addBreadcrumb,\n addFetchInstrumentationHandler,\n defineIntegration,\n getBreadcrumbLogLevelFromHttpStatusCode,\n getClient,\n instrumentFetchRequest,\n isSentryRequestUrl,\n LRUMap,\n stringMatchesSomePattern,\n} from '@sentry/core';\n\nconst INTEGRATION_NAME = 'Fetch';\n\nconst HAS_CLIENT_MAP = new WeakMap<Client, boolean>();\n\nexport interface Options {\n /**\n * Whether breadcrumbs should be recorded for requests\n * Defaults to true\n */\n breadcrumbs: boolean;\n\n /**\n * Function determining whether or not to create spans to track outgoing requests to the given URL.\n * By default, spans will be created for all outgoing requests.\n */\n shouldCreateSpanForRequest?: (url: string) => boolean;\n}\n\nconst _fetchIntegration = ((options: Partial<Options> = {}) => {\n const breadcrumbs = options.breadcrumbs === undefined ? true : options.breadcrumbs;\n const shouldCreateSpanForRequest = options.shouldCreateSpanForRequest;\n\n const _createSpanUrlMap = new LRUMap<string, boolean>(100);\n const _headersUrlMap = new LRUMap<string, boolean>(100);\n\n const spans: Record<string, Span> = {};\n\n /** Decides whether to attach trace data to the outgoing fetch request */\n function _shouldAttachTraceData(url: string): boolean {\n const client = getClient();\n\n if (!client) {\n return false;\n }\n\n const clientOptions = client.getOptions();\n\n if (clientOptions.tracePropagationTargets === undefined) {\n return true;\n }\n\n const cachedDecision = _headersUrlMap.get(url);\n if (cachedDecision !== undefined) {\n return cachedDecision;\n }\n\n const decision = stringMatchesSomePattern(url, clientOptions.tracePropagationTargets);\n _headersUrlMap.set(url, decision);\n return decision;\n }\n\n /** Helper that wraps shouldCreateSpanForRequest option */\n function _shouldCreateSpan(url: string): boolean {\n if (shouldCreateSpanForRequest === undefined) {\n return true;\n }\n\n const cachedDecision = _createSpanUrlMap.get(url);\n if (cachedDecision !== undefined) {\n return cachedDecision;\n }\n\n const decision = shouldCreateSpanForRequest(url);\n _createSpanUrlMap.set(url, decision);\n return decision;\n }\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n addFetchInstrumentationHandler(handlerData => {\n const client = getClient();\n const { propagateTraceparent } = client?.getOptions() || {};\n if (!client || !HAS_CLIENT_MAP.get(client)) {\n return;\n }\n\n if (isSentryRequestUrl(handlerData.fetchData.url, client)) {\n return;\n }\n\n instrumentFetchRequest(handlerData, _shouldCreateSpan, _shouldAttachTraceData, spans, {\n spanOrigin: 'auto.http.fetch',\n propagateTraceparent,\n });\n\n if (breadcrumbs) {\n createBreadcrumb(handlerData);\n }\n }, true);\n },\n setup(client) {\n HAS_CLIENT_MAP.set(client, true);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Creates spans and attaches tracing headers to fetch requests.\n */\nexport const fetchIntegration = defineIntegration(_fetchIntegration);\n\nfunction createBreadcrumb(handlerData: HandlerDataFetch): void {\n const { startTimestamp, endTimestamp } = handlerData;\n\n // We only capture complete fetch requests\n if (!endTimestamp) {\n return;\n }\n\n const breadcrumbData: FetchBreadcrumbData = {\n method: handlerData.fetchData.method,\n url: handlerData.fetchData.url,\n };\n\n if (handlerData.error) {\n const hint: FetchBreadcrumbHint = {\n data: handlerData.error,\n input: handlerData.args,\n startTimestamp,\n endTimestamp,\n };\n\n addBreadcrumb(\n {\n category: 'fetch',\n data: breadcrumbData,\n level: 'error',\n type: 'http',\n },\n hint,\n );\n } else {\n const response = handlerData.response as Response | undefined;\n\n breadcrumbData.request_body_size = handlerData.fetchData.request_body_size;\n breadcrumbData.response_body_size = handlerData.fetchData.response_body_size;\n breadcrumbData.status_code = response?.status;\n\n const hint: FetchBreadcrumbHint = {\n input: handlerData.args,\n response,\n startTimestamp,\n endTimestamp,\n };\n const level = getBreadcrumbLogLevelFromHttpStatusCode(breadcrumbData.status_code);\n\n addBreadcrumb(\n {\n category: 'fetch',\n data: breadcrumbData,\n type: 'http',\n level,\n },\n hint,\n );\n }\n}\n"],"names":["LRUMap","getClient","stringMatchesSomePattern","addFetchInstrumentationHandler","isSentryRequestUrl","instrumentFetchRequest","defineIntegration","addBreadcrumb","getBreadcrumbLogLevelFromHttpStatusCode"],"mappings":"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"}
@@ -28,8 +28,8 @@ class SentryCloudflareTraceProvider {constructor() { SentryCloudflareTraceProvi
28
28
  class SentryCloudflareTracer {
29
29
  startSpan(name, options) {
30
30
  return core.startInactiveSpan({
31
- name,
32
31
  ...options,
32
+ name,
33
33
  attributes: {
34
34
  ...options?.attributes,
35
35
  'sentry.cloudflare_tracer': true,
@@ -50,8 +50,8 @@ class SentryCloudflareTracer {
50
50
  const opts = (typeof options === 'object' && options !== null ? options : {}) ;
51
51
 
52
52
  const spanOpts = {
53
- name,
54
53
  ...opts,
54
+ name,
55
55
  attributes: {
56
56
  ...opts.attributes,
57
57
  'sentry.cloudflare_tracer': true,
@@ -1 +1 @@
1
- {"version":3,"file":"tracer.js","sources":["../../../src/opentelemetry/tracer.ts"],"sourcesContent":["import type { Context, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';\nimport { trace } from '@opentelemetry/api';\nimport { startInactiveSpan, startSpanManual } from '@sentry/core';\n\n/**\n * Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans.\n * This is not perfect but handles easy/common use cases.\n */\nexport function setupOpenTelemetryTracer(): void {\n trace.setGlobalTracerProvider(new SentryCloudflareTraceProvider());\n}\n\nclass SentryCloudflareTraceProvider implements TracerProvider {\n private readonly _tracers: Map<string, Tracer> = new Map();\n\n public getTracer(name: string, version?: string, options?: { schemaUrl?: string }): Tracer {\n const key = `${name}@${version || ''}:${options?.schemaUrl || ''}`;\n if (!this._tracers.has(key)) {\n this._tracers.set(key, new SentryCloudflareTracer());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this._tracers.get(key)!;\n }\n}\n\nclass SentryCloudflareTracer implements Tracer {\n public startSpan(name: string, options?: SpanOptions): Span {\n return startInactiveSpan({\n name,\n ...options,\n attributes: {\n ...options?.attributes,\n 'sentry.cloudflare_tracer': true,\n },\n });\n }\n\n /**\n * NOTE: This does not handle `context` being passed in. It will always put spans on the current scope.\n */\n public startActiveSpan<F extends (span: Span) => unknown>(name: string, fn: F): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(name: string, options: SpanOptions, fn: F): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(\n name: string,\n options: SpanOptions,\n context: Context,\n fn: F,\n ): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(\n name: string,\n options: unknown,\n context?: unknown,\n fn?: F,\n ): ReturnType<F> {\n const opts = (typeof options === 'object' && options !== null ? options : {}) as SpanOptions;\n\n const spanOpts = {\n name,\n ...opts,\n attributes: {\n ...opts.attributes,\n 'sentry.cloudflare_tracer': true,\n },\n };\n\n const callback = (\n typeof options === 'function'\n ? options\n : typeof context === 'function'\n ? context\n : typeof fn === 'function'\n ? fn\n : () => {}\n ) as F;\n\n // In OTEL the semantic matches `startSpanManual` because spans are not auto-ended\n return startSpanManual(spanOpts, callback) as ReturnType<F>;\n }\n}\n"],"names":["trace","startInactiveSpan","startSpanManual"],"mappings":";;;;;AAIA;AACA;AACA;AACA;AACO,SAAS,wBAAwB,GAAS;AACjD,EAAEA,SAAK,CAAC,uBAAuB,CAAC,IAAI,6BAA6B,EAAE,CAAC;AACpE;;AAEA,MAAM,+BAAwD,CAAA,WAAA,GAAA,EAAA,6BAAA,CAAA,SAAA,CAAA,MAAA,CAAA,IAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AAC9D,mBAAmB,QAAQ,GAAwB,IAAI,GAAG,GAAC;;AAE3D,GAAS,SAAS,CAAC,IAAI,EAAU,OAAO,EAAW,OAAO,EAAmC;AAC7F,IAAI,MAAM,GAAA,GAAM,CAAC,EAAA,IAAA,CAAA,CAAA,EAAA,OAAA,IAAA,EAAA,CAAA,CAAA,EAAA,OAAA,EAAA,SAAA,IAAA,EAAA,CAAA,CAAA;AACA,IAAA,IAAA,CAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,CAAA,EAAA;AACA,MAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,EAAA,IAAA,sBAAA,EAAA,CAAA;AACA,IAAA;;AAEA;AACA,IAAA,OAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,CAAA;AACA,EAAA;AACA;;AAEA,MAAA,sBAAA,EAAA;AACA,GAAA,SAAA,CAAA,IAAA,EAAA,OAAA,EAAA;AACA,IAAA,OAAAC,sBAAA,CAAA;AACA,MAAA,IAAA;AACA,MAAA,GAAA,OAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,GAAA,OAAA,EAAA,UAAA;AACA,QAAA,0BAAA,EAAA,IAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA,EAAA;;AAEA;AACA;AACA;;AASA,GAAA,eAAA;AACA,IAAA,IAAA;AACA,IAAA,OAAA;AACA,IAAA,OAAA;AACA,IAAA,EAAA;AACA,IAAA;AACA,IAAA,MAAA,IAAA,IAAA,OAAA,OAAA,KAAA,QAAA,IAAA,OAAA,KAAA,IAAA,GAAA,OAAA,GAAA,EAAA,CAAA;;AAEA,IAAA,MAAA,QAAA,GAAA;AACA,MAAA,IAAA;AACA,MAAA,GAAA,IAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,GAAA,IAAA,CAAA,UAAA;AACA,QAAA,0BAAA,EAAA,IAAA;AACA,OAAA;AACA,KAAA;;AAEA,IAAA,MAAA,QAAA;AACA,MAAA,OAAA,OAAA,KAAA;AACA,UAAA;AACA,UAAA,OAAA,OAAA,KAAA;AACA,YAAA;AACA,YAAA,OAAA,EAAA,KAAA;AACA,cAAA;AACA,cAAA,MAAA,CAAA;AACA,KAAA;;AAEA;AACA,IAAA,OAAAC,oBAAA,CAAA,QAAA,EAAA,QAAA,CAAA;AACA,EAAA;AACA;;;;"}
1
+ {"version":3,"file":"tracer.js","sources":["../../../src/opentelemetry/tracer.ts"],"sourcesContent":["import type { Context, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';\nimport { trace } from '@opentelemetry/api';\nimport { startInactiveSpan, startSpanManual } from '@sentry/core';\n\n/**\n * Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans.\n * This is not perfect but handles easy/common use cases.\n */\nexport function setupOpenTelemetryTracer(): void {\n trace.setGlobalTracerProvider(new SentryCloudflareTraceProvider());\n}\n\nclass SentryCloudflareTraceProvider implements TracerProvider {\n private readonly _tracers: Map<string, Tracer> = new Map();\n\n public getTracer(name: string, version?: string, options?: { schemaUrl?: string }): Tracer {\n const key = `${name}@${version || ''}:${options?.schemaUrl || ''}`;\n if (!this._tracers.has(key)) {\n this._tracers.set(key, new SentryCloudflareTracer());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this._tracers.get(key)!;\n }\n}\n\nclass SentryCloudflareTracer implements Tracer {\n public startSpan(name: string, options?: SpanOptions): Span {\n return startInactiveSpan({\n ...options,\n name,\n attributes: {\n ...options?.attributes,\n 'sentry.cloudflare_tracer': true,\n },\n });\n }\n\n /**\n * NOTE: This does not handle `context` being passed in. It will always put spans on the current scope.\n */\n public startActiveSpan<F extends (span: Span) => unknown>(name: string, fn: F): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(name: string, options: SpanOptions, fn: F): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(\n name: string,\n options: SpanOptions,\n context: Context,\n fn: F,\n ): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(\n name: string,\n options: unknown,\n context?: unknown,\n fn?: F,\n ): ReturnType<F> {\n const opts = (typeof options === 'object' && options !== null ? options : {}) as SpanOptions;\n\n const spanOpts = {\n ...opts,\n name,\n attributes: {\n ...opts.attributes,\n 'sentry.cloudflare_tracer': true,\n },\n };\n\n const callback = (\n typeof options === 'function'\n ? options\n : typeof context === 'function'\n ? context\n : typeof fn === 'function'\n ? fn\n : () => {}\n ) as F;\n\n // In OTEL the semantic matches `startSpanManual` because spans are not auto-ended\n return startSpanManual(spanOpts, callback) as ReturnType<F>;\n }\n}\n"],"names":["trace","startInactiveSpan","startSpanManual"],"mappings":";;;;;AAIA;AACA;AACA;AACA;AACO,SAAS,wBAAwB,GAAS;AACjD,EAAEA,SAAK,CAAC,uBAAuB,CAAC,IAAI,6BAA6B,EAAE,CAAC;AACpE;;AAEA,MAAM,+BAAwD,CAAA,WAAA,GAAA,EAAA,6BAAA,CAAA,SAAA,CAAA,MAAA,CAAA,IAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AAC9D,mBAAmB,QAAQ,GAAwB,IAAI,GAAG,GAAC;;AAE3D,GAAS,SAAS,CAAC,IAAI,EAAU,OAAO,EAAW,OAAO,EAAmC;AAC7F,IAAI,MAAM,GAAA,GAAM,CAAC,EAAA,IAAA,CAAA,CAAA,EAAA,OAAA,IAAA,EAAA,CAAA,CAAA,EAAA,OAAA,EAAA,SAAA,IAAA,EAAA,CAAA,CAAA;AACA,IAAA,IAAA,CAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,CAAA,EAAA;AACA,MAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,EAAA,IAAA,sBAAA,EAAA,CAAA;AACA,IAAA;;AAEA;AACA,IAAA,OAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,CAAA;AACA,EAAA;AACA;;AAEA,MAAA,sBAAA,EAAA;AACA,GAAA,SAAA,CAAA,IAAA,EAAA,OAAA,EAAA;AACA,IAAA,OAAAC,sBAAA,CAAA;AACA,MAAA,GAAA,OAAA;AACA,MAAA,IAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,GAAA,OAAA,EAAA,UAAA;AACA,QAAA,0BAAA,EAAA,IAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA,EAAA;;AAEA;AACA;AACA;;AASA,GAAA,eAAA;AACA,IAAA,IAAA;AACA,IAAA,OAAA;AACA,IAAA,OAAA;AACA,IAAA,EAAA;AACA,IAAA;AACA,IAAA,MAAA,IAAA,IAAA,OAAA,OAAA,KAAA,QAAA,IAAA,OAAA,KAAA,IAAA,GAAA,OAAA,GAAA,EAAA,CAAA;;AAEA,IAAA,MAAA,QAAA,GAAA;AACA,MAAA,GAAA,IAAA;AACA,MAAA,IAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,GAAA,IAAA,CAAA,UAAA;AACA,QAAA,0BAAA,EAAA,IAAA;AACA,OAAA;AACA,KAAA;;AAEA,IAAA,MAAA,QAAA;AACA,MAAA,OAAA,OAAA,KAAA;AACA,UAAA;AACA,UAAA,OAAA,OAAA,KAAA;AACA,YAAA;AACA,YAAA,OAAA,EAAA,KAAA;AACA,cAAA;AACA,cAAA,MAAA,CAAA;AACA,KAAA;;AAEA;AACA,IAAA,OAAAC,oBAAA,CAAA,QAAA,EAAA,QAAA,CAAA;AACA,EAAA;AACA;;;;"}
@@ -78,7 +78,18 @@ function makeCloudflareTransport(options) {
78
78
  };
79
79
 
80
80
  return core.suppressTracing(() => {
81
- return (options.fetch ?? fetch)(options.url, requestOptions).then(response => {
81
+ return (options.fetch ?? fetch)(options.url, requestOptions).then(async response => {
82
+ // Consume the response body to satisfy Cloudflare Workers' fetch requirements.
83
+ // The runtime requires all fetch response bodies to be read or explicitly canceled
84
+ // to prevent connection stalls and potential deadlocks. We read the body as text
85
+ // even though we don't use the content, as Sentry's response information is in the headers.
86
+ // See: https://github.com/getsentry/sentry-javascript/issues/18534
87
+ try {
88
+ await response.text();
89
+ } catch {
90
+ // no-op
91
+ }
92
+
82
93
  return {
83
94
  statusCode: response.status,
84
95
  headers: {
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sources":["../../src/transport.ts"],"sourcesContent":["import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core';\nimport { createTransport, SENTRY_BUFFER_FULL_ERROR, suppressTracing } from '@sentry/core';\n\nexport interface CloudflareTransportOptions extends BaseTransportOptions {\n /** Custom fetch function to use. This allows usage of things like Workers VPC */\n fetch?: typeof fetch;\n /** Fetch API init parameters. */\n fetchOptions?: RequestInit;\n}\n\nconst DEFAULT_TRANSPORT_BUFFER_SIZE = 30;\n\n/**\n * This is a modified promise buffer that collects tasks until drain is called.\n * We need this in the edge runtime because edge function invocations may not share I/O objects, like fetch requests\n * and responses, and the normal PromiseBuffer inherently buffers stuff inbetween incoming requests.\n *\n * A limitation we need to be aware of is that DEFAULT_TRANSPORT_BUFFER_SIZE is the maximum amount of payloads the\n * SDK can send for a given edge function invocation.\n */\nexport class IsolatedPromiseBuffer {\n // We just have this field because the promise buffer interface requires it.\n // If we ever remove it from the interface we should also remove it here.\n public $: Array<PromiseLike<TransportMakeRequestResponse>>;\n\n private _taskProducers: (() => PromiseLike<TransportMakeRequestResponse>)[];\n\n private readonly _bufferSize: number;\n\n public constructor(_bufferSize = DEFAULT_TRANSPORT_BUFFER_SIZE) {\n this.$ = [];\n this._taskProducers = [];\n this._bufferSize = _bufferSize;\n }\n\n /**\n * @inheritdoc\n */\n public add(taskProducer: () => PromiseLike<TransportMakeRequestResponse>): PromiseLike<TransportMakeRequestResponse> {\n if (this._taskProducers.length >= this._bufferSize) {\n return Promise.reject(SENTRY_BUFFER_FULL_ERROR);\n }\n\n this._taskProducers.push(taskProducer);\n return Promise.resolve({});\n }\n\n /**\n * @inheritdoc\n */\n public drain(timeout?: number): PromiseLike<boolean> {\n const oldTaskProducers = [...this._taskProducers];\n this._taskProducers = [];\n\n return new Promise(resolve => {\n const timer = setTimeout(() => {\n if (timeout && timeout > 0) {\n resolve(false);\n }\n }, timeout);\n\n // This cannot reject\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n Promise.all(\n oldTaskProducers.map(taskProducer =>\n taskProducer().then(null, () => {\n // catch all failed requests\n }),\n ),\n ).then(() => {\n // resolve to true if all fetch requests settled\n clearTimeout(timer);\n resolve(true);\n });\n });\n }\n}\n\n/**\n * Creates a Transport that uses the native fetch API to send events to Sentry.\n */\nexport function makeCloudflareTransport(options: CloudflareTransportOptions): Transport {\n function makeRequest(request: TransportRequest): PromiseLike<TransportMakeRequestResponse> {\n const requestOptions: RequestInit = {\n body: request.body,\n method: 'POST',\n headers: options.headers,\n ...options.fetchOptions,\n };\n\n return suppressTracing(() => {\n return (options.fetch ?? fetch)(options.url, requestOptions).then(response => {\n return {\n statusCode: response.status,\n headers: {\n 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),\n 'retry-after': response.headers.get('Retry-After'),\n },\n };\n });\n });\n }\n\n return createTransport(options, makeRequest, new IsolatedPromiseBuffer(options.bufferSize));\n}\n"],"names":["SENTRY_BUFFER_FULL_ERROR","suppressTracing","createTransport"],"mappings":";;;;AAUA,MAAM,6BAAA,GAAgC,EAAE;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,qBAAA,CAAsB;AACnC;AACA;;AAOA,GAAS,WAAW,CAAC,WAAA,GAAc,6BAA6B,EAAE;AAClE,IAAI,IAAI,CAAC,CAAA,GAAI,EAAE;AACf,IAAI,IAAI,CAAC,cAAA,GAAiB,EAAE;AAC5B,IAAI,IAAI,CAAC,WAAA,GAAc,WAAW;AAClC,EAAE;;AAEF;AACA;AACA;AACA,GAAS,GAAG,CAAC,YAAY,EAA8F;AACvH,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,MAAA,IAAU,IAAI,CAAC,WAAW,EAAE;AACxD,MAAM,OAAO,OAAO,CAAC,MAAM,CAACA,6BAAwB,CAAC;AACrD,IAAI;;AAEJ,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;AAC1C,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;AAC9B,EAAE;;AAEF;AACA;AACA;AACA,GAAS,KAAK,CAAC,OAAO,EAAiC;AACvD,IAAI,MAAM,mBAAmB,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;AACrD,IAAI,IAAI,CAAC,cAAA,GAAiB,EAAE;;AAE5B,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW;AAClC,MAAM,MAAM,KAAA,GAAQ,UAAU,CAAC,MAAM;AACrC,QAAQ,IAAI,OAAA,IAAW,OAAA,GAAU,CAAC,EAAE;AACpC,UAAU,OAAO,CAAC,KAAK,CAAC;AACxB,QAAQ;AACR,MAAM,CAAC,EAAE,OAAO,CAAC;;AAEjB;AACA;AACA,MAAM,OAAO,CAAC,GAAG;AACjB,QAAQ,gBAAgB,CAAC,GAAG,CAAC,YAAA;AAC7B,UAAU,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;AAC1C;AACA,UAAU,CAAC,CAAC;AACZ,SAAS;AACT,OAAO,CAAC,IAAI,CAAC,MAAM;AACnB;AACA,QAAQ,YAAY,CAAC,KAAK,CAAC;AAC3B,QAAQ,OAAO,CAAC,IAAI,CAAC;AACrB,MAAM,CAAC,CAAC;AACR,IAAI,CAAC,CAAC;AACN,EAAE;AACF;;AAEA;AACA;AACA;AACO,SAAS,uBAAuB,CAAC,OAAO,EAAyC;AACxF,EAAE,SAAS,WAAW,CAAC,OAAO,EAA+D;AAC7F,IAAI,MAAM,cAAc,GAAgB;AACxC,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI;AACxB,MAAM,MAAM,EAAE,MAAM;AACpB,MAAM,OAAO,EAAE,OAAO,CAAC,OAAO;AAC9B,MAAM,GAAG,OAAO,CAAC,YAAY;AAC7B,KAAK;;AAEL,IAAI,OAAOC,oBAAe,CAAC,MAAM;AACjC,MAAM,OAAO,CAAC,OAAO,CAAC,KAAA,IAAS,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,YAAY;AACpF,QAAQ,OAAO;AACf,UAAU,UAAU,EAAE,QAAQ,CAAC,MAAM;AACrC,UAAU,OAAO,EAAE;AACnB,YAAY,sBAAsB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;AAChF,YAAY,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;AAC9D,WAAW;AACX,SAAS;AACT,MAAM,CAAC,CAAC;AACR,IAAI,CAAC,CAAC;AACN,EAAE;;AAEF,EAAE,OAAOC,oBAAe,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC7F;;;;;"}
1
+ {"version":3,"file":"transport.js","sources":["../../src/transport.ts"],"sourcesContent":["import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core';\nimport { createTransport, SENTRY_BUFFER_FULL_ERROR, suppressTracing } from '@sentry/core';\n\nexport interface CloudflareTransportOptions extends BaseTransportOptions {\n /** Custom fetch function to use. This allows usage of things like Workers VPC */\n fetch?: typeof fetch;\n /** Fetch API init parameters. */\n fetchOptions?: RequestInit;\n}\n\nconst DEFAULT_TRANSPORT_BUFFER_SIZE = 30;\n\n/**\n * This is a modified promise buffer that collects tasks until drain is called.\n * We need this in the edge runtime because edge function invocations may not share I/O objects, like fetch requests\n * and responses, and the normal PromiseBuffer inherently buffers stuff inbetween incoming requests.\n *\n * A limitation we need to be aware of is that DEFAULT_TRANSPORT_BUFFER_SIZE is the maximum amount of payloads the\n * SDK can send for a given edge function invocation.\n */\nexport class IsolatedPromiseBuffer {\n // We just have this field because the promise buffer interface requires it.\n // If we ever remove it from the interface we should also remove it here.\n public $: Array<PromiseLike<TransportMakeRequestResponse>>;\n\n private _taskProducers: (() => PromiseLike<TransportMakeRequestResponse>)[];\n\n private readonly _bufferSize: number;\n\n public constructor(_bufferSize = DEFAULT_TRANSPORT_BUFFER_SIZE) {\n this.$ = [];\n this._taskProducers = [];\n this._bufferSize = _bufferSize;\n }\n\n /**\n * @inheritdoc\n */\n public add(taskProducer: () => PromiseLike<TransportMakeRequestResponse>): PromiseLike<TransportMakeRequestResponse> {\n if (this._taskProducers.length >= this._bufferSize) {\n return Promise.reject(SENTRY_BUFFER_FULL_ERROR);\n }\n\n this._taskProducers.push(taskProducer);\n return Promise.resolve({});\n }\n\n /**\n * @inheritdoc\n */\n public drain(timeout?: number): PromiseLike<boolean> {\n const oldTaskProducers = [...this._taskProducers];\n this._taskProducers = [];\n\n return new Promise(resolve => {\n const timer = setTimeout(() => {\n if (timeout && timeout > 0) {\n resolve(false);\n }\n }, timeout);\n\n // This cannot reject\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n Promise.all(\n oldTaskProducers.map(taskProducer =>\n taskProducer().then(null, () => {\n // catch all failed requests\n }),\n ),\n ).then(() => {\n // resolve to true if all fetch requests settled\n clearTimeout(timer);\n resolve(true);\n });\n });\n }\n}\n\n/**\n * Creates a Transport that uses the native fetch API to send events to Sentry.\n */\nexport function makeCloudflareTransport(options: CloudflareTransportOptions): Transport {\n function makeRequest(request: TransportRequest): PromiseLike<TransportMakeRequestResponse> {\n const requestOptions: RequestInit = {\n body: request.body,\n method: 'POST',\n headers: options.headers,\n ...options.fetchOptions,\n };\n\n return suppressTracing(() => {\n return (options.fetch ?? fetch)(options.url, requestOptions).then(async response => {\n // Consume the response body to satisfy Cloudflare Workers' fetch requirements.\n // The runtime requires all fetch response bodies to be read or explicitly canceled\n // to prevent connection stalls and potential deadlocks. We read the body as text\n // even though we don't use the content, as Sentry's response information is in the headers.\n // See: https://github.com/getsentry/sentry-javascript/issues/18534\n try {\n await response.text();\n } catch {\n // no-op\n }\n\n return {\n statusCode: response.status,\n headers: {\n 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),\n 'retry-after': response.headers.get('Retry-After'),\n },\n };\n });\n });\n }\n\n return createTransport(options, makeRequest, new IsolatedPromiseBuffer(options.bufferSize));\n}\n"],"names":["SENTRY_BUFFER_FULL_ERROR","suppressTracing","createTransport"],"mappings":"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"}
@@ -58,6 +58,7 @@ const _fetchIntegration = ((options = {}) => {
58
58
  setupOnce() {
59
59
  addFetchInstrumentationHandler(handlerData => {
60
60
  const client = getClient();
61
+ const { propagateTraceparent } = client?.getOptions() || {};
61
62
  if (!client || !HAS_CLIENT_MAP.get(client)) {
62
63
  return;
63
64
  }
@@ -68,6 +69,7 @@ const _fetchIntegration = ((options = {}) => {
68
69
 
69
70
  instrumentFetchRequest(handlerData, _shouldCreateSpan, _shouldAttachTraceData, spans, {
70
71
  spanOrigin: 'auto.http.fetch',
72
+ propagateTraceparent,
71
73
  });
72
74
 
73
75
  if (breadcrumbs) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sources":["../../../src/integrations/fetch.ts"],"sourcesContent":["import type {\n Client,\n FetchBreadcrumbData,\n FetchBreadcrumbHint,\n HandlerDataFetch,\n IntegrationFn,\n Span,\n} from '@sentry/core';\nimport {\n addBreadcrumb,\n addFetchInstrumentationHandler,\n defineIntegration,\n getBreadcrumbLogLevelFromHttpStatusCode,\n getClient,\n instrumentFetchRequest,\n isSentryRequestUrl,\n LRUMap,\n stringMatchesSomePattern,\n} from '@sentry/core';\n\nconst INTEGRATION_NAME = 'Fetch';\n\nconst HAS_CLIENT_MAP = new WeakMap<Client, boolean>();\n\nexport interface Options {\n /**\n * Whether breadcrumbs should be recorded for requests\n * Defaults to true\n */\n breadcrumbs: boolean;\n\n /**\n * Function determining whether or not to create spans to track outgoing requests to the given URL.\n * By default, spans will be created for all outgoing requests.\n */\n shouldCreateSpanForRequest?: (url: string) => boolean;\n}\n\nconst _fetchIntegration = ((options: Partial<Options> = {}) => {\n const breadcrumbs = options.breadcrumbs === undefined ? true : options.breadcrumbs;\n const shouldCreateSpanForRequest = options.shouldCreateSpanForRequest;\n\n const _createSpanUrlMap = new LRUMap<string, boolean>(100);\n const _headersUrlMap = new LRUMap<string, boolean>(100);\n\n const spans: Record<string, Span> = {};\n\n /** Decides whether to attach trace data to the outgoing fetch request */\n function _shouldAttachTraceData(url: string): boolean {\n const client = getClient();\n\n if (!client) {\n return false;\n }\n\n const clientOptions = client.getOptions();\n\n if (clientOptions.tracePropagationTargets === undefined) {\n return true;\n }\n\n const cachedDecision = _headersUrlMap.get(url);\n if (cachedDecision !== undefined) {\n return cachedDecision;\n }\n\n const decision = stringMatchesSomePattern(url, clientOptions.tracePropagationTargets);\n _headersUrlMap.set(url, decision);\n return decision;\n }\n\n /** Helper that wraps shouldCreateSpanForRequest option */\n function _shouldCreateSpan(url: string): boolean {\n if (shouldCreateSpanForRequest === undefined) {\n return true;\n }\n\n const cachedDecision = _createSpanUrlMap.get(url);\n if (cachedDecision !== undefined) {\n return cachedDecision;\n }\n\n const decision = shouldCreateSpanForRequest(url);\n _createSpanUrlMap.set(url, decision);\n return decision;\n }\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n addFetchInstrumentationHandler(handlerData => {\n const client = getClient();\n if (!client || !HAS_CLIENT_MAP.get(client)) {\n return;\n }\n\n if (isSentryRequestUrl(handlerData.fetchData.url, client)) {\n return;\n }\n\n instrumentFetchRequest(handlerData, _shouldCreateSpan, _shouldAttachTraceData, spans, {\n spanOrigin: 'auto.http.fetch',\n });\n\n if (breadcrumbs) {\n createBreadcrumb(handlerData);\n }\n }, true);\n },\n setup(client) {\n HAS_CLIENT_MAP.set(client, true);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Creates spans and attaches tracing headers to fetch requests.\n */\nexport const fetchIntegration = defineIntegration(_fetchIntegration);\n\nfunction createBreadcrumb(handlerData: HandlerDataFetch): void {\n const { startTimestamp, endTimestamp } = handlerData;\n\n // We only capture complete fetch requests\n if (!endTimestamp) {\n return;\n }\n\n const breadcrumbData: FetchBreadcrumbData = {\n method: handlerData.fetchData.method,\n url: handlerData.fetchData.url,\n };\n\n if (handlerData.error) {\n const hint: FetchBreadcrumbHint = {\n data: handlerData.error,\n input: handlerData.args,\n startTimestamp,\n endTimestamp,\n };\n\n addBreadcrumb(\n {\n category: 'fetch',\n data: breadcrumbData,\n level: 'error',\n type: 'http',\n },\n hint,\n );\n } else {\n const response = handlerData.response as Response | undefined;\n\n breadcrumbData.request_body_size = handlerData.fetchData.request_body_size;\n breadcrumbData.response_body_size = handlerData.fetchData.response_body_size;\n breadcrumbData.status_code = response?.status;\n\n const hint: FetchBreadcrumbHint = {\n input: handlerData.args,\n response,\n startTimestamp,\n endTimestamp,\n };\n const level = getBreadcrumbLogLevelFromHttpStatusCode(breadcrumbData.status_code);\n\n addBreadcrumb(\n {\n category: 'fetch',\n data: breadcrumbData,\n type: 'http',\n level,\n },\n hint,\n );\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch.js","sources":["../../../src/integrations/fetch.ts"],"sourcesContent":["import type {\n Client,\n FetchBreadcrumbData,\n FetchBreadcrumbHint,\n HandlerDataFetch,\n IntegrationFn,\n Span,\n} from '@sentry/core';\nimport {\n addBreadcrumb,\n addFetchInstrumentationHandler,\n defineIntegration,\n getBreadcrumbLogLevelFromHttpStatusCode,\n getClient,\n instrumentFetchRequest,\n isSentryRequestUrl,\n LRUMap,\n stringMatchesSomePattern,\n} from '@sentry/core';\n\nconst INTEGRATION_NAME = 'Fetch';\n\nconst HAS_CLIENT_MAP = new WeakMap<Client, boolean>();\n\nexport interface Options {\n /**\n * Whether breadcrumbs should be recorded for requests\n * Defaults to true\n */\n breadcrumbs: boolean;\n\n /**\n * Function determining whether or not to create spans to track outgoing requests to the given URL.\n * By default, spans will be created for all outgoing requests.\n */\n shouldCreateSpanForRequest?: (url: string) => boolean;\n}\n\nconst _fetchIntegration = ((options: Partial<Options> = {}) => {\n const breadcrumbs = options.breadcrumbs === undefined ? true : options.breadcrumbs;\n const shouldCreateSpanForRequest = options.shouldCreateSpanForRequest;\n\n const _createSpanUrlMap = new LRUMap<string, boolean>(100);\n const _headersUrlMap = new LRUMap<string, boolean>(100);\n\n const spans: Record<string, Span> = {};\n\n /** Decides whether to attach trace data to the outgoing fetch request */\n function _shouldAttachTraceData(url: string): boolean {\n const client = getClient();\n\n if (!client) {\n return false;\n }\n\n const clientOptions = client.getOptions();\n\n if (clientOptions.tracePropagationTargets === undefined) {\n return true;\n }\n\n const cachedDecision = _headersUrlMap.get(url);\n if (cachedDecision !== undefined) {\n return cachedDecision;\n }\n\n const decision = stringMatchesSomePattern(url, clientOptions.tracePropagationTargets);\n _headersUrlMap.set(url, decision);\n return decision;\n }\n\n /** Helper that wraps shouldCreateSpanForRequest option */\n function _shouldCreateSpan(url: string): boolean {\n if (shouldCreateSpanForRequest === undefined) {\n return true;\n }\n\n const cachedDecision = _createSpanUrlMap.get(url);\n if (cachedDecision !== undefined) {\n return cachedDecision;\n }\n\n const decision = shouldCreateSpanForRequest(url);\n _createSpanUrlMap.set(url, decision);\n return decision;\n }\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n addFetchInstrumentationHandler(handlerData => {\n const client = getClient();\n const { propagateTraceparent } = client?.getOptions() || {};\n if (!client || !HAS_CLIENT_MAP.get(client)) {\n return;\n }\n\n if (isSentryRequestUrl(handlerData.fetchData.url, client)) {\n return;\n }\n\n instrumentFetchRequest(handlerData, _shouldCreateSpan, _shouldAttachTraceData, spans, {\n spanOrigin: 'auto.http.fetch',\n propagateTraceparent,\n });\n\n if (breadcrumbs) {\n createBreadcrumb(handlerData);\n }\n }, true);\n },\n setup(client) {\n HAS_CLIENT_MAP.set(client, true);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Creates spans and attaches tracing headers to fetch requests.\n */\nexport const fetchIntegration = defineIntegration(_fetchIntegration);\n\nfunction createBreadcrumb(handlerData: HandlerDataFetch): void {\n const { startTimestamp, endTimestamp } = handlerData;\n\n // We only capture complete fetch requests\n if (!endTimestamp) {\n return;\n }\n\n const breadcrumbData: FetchBreadcrumbData = {\n method: handlerData.fetchData.method,\n url: handlerData.fetchData.url,\n };\n\n if (handlerData.error) {\n const hint: FetchBreadcrumbHint = {\n data: handlerData.error,\n input: handlerData.args,\n startTimestamp,\n endTimestamp,\n };\n\n addBreadcrumb(\n {\n category: 'fetch',\n data: breadcrumbData,\n level: 'error',\n type: 'http',\n },\n hint,\n );\n } else {\n const response = handlerData.response as Response | undefined;\n\n breadcrumbData.request_body_size = handlerData.fetchData.request_body_size;\n breadcrumbData.response_body_size = handlerData.fetchData.response_body_size;\n breadcrumbData.status_code = response?.status;\n\n const hint: FetchBreadcrumbHint = {\n input: handlerData.args,\n response,\n startTimestamp,\n endTimestamp,\n };\n const level = getBreadcrumbLogLevelFromHttpStatusCode(breadcrumbData.status_code);\n\n addBreadcrumb(\n {\n category: 'fetch',\n data: breadcrumbData,\n type: 'http',\n level,\n },\n hint,\n );\n }\n}\n"],"names":[],"mappings":"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"}
@@ -26,8 +26,8 @@ class SentryCloudflareTraceProvider {constructor() { SentryCloudflareTraceProvi
26
26
  class SentryCloudflareTracer {
27
27
  startSpan(name, options) {
28
28
  return startInactiveSpan({
29
- name,
30
29
  ...options,
30
+ name,
31
31
  attributes: {
32
32
  ...options?.attributes,
33
33
  'sentry.cloudflare_tracer': true,
@@ -48,8 +48,8 @@ class SentryCloudflareTracer {
48
48
  const opts = (typeof options === 'object' && options !== null ? options : {}) ;
49
49
 
50
50
  const spanOpts = {
51
- name,
52
51
  ...opts,
52
+ name,
53
53
  attributes: {
54
54
  ...opts.attributes,
55
55
  'sentry.cloudflare_tracer': true,
@@ -1 +1 @@
1
- {"version":3,"file":"tracer.js","sources":["../../../src/opentelemetry/tracer.ts"],"sourcesContent":["import type { Context, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';\nimport { trace } from '@opentelemetry/api';\nimport { startInactiveSpan, startSpanManual } from '@sentry/core';\n\n/**\n * Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans.\n * This is not perfect but handles easy/common use cases.\n */\nexport function setupOpenTelemetryTracer(): void {\n trace.setGlobalTracerProvider(new SentryCloudflareTraceProvider());\n}\n\nclass SentryCloudflareTraceProvider implements TracerProvider {\n private readonly _tracers: Map<string, Tracer> = new Map();\n\n public getTracer(name: string, version?: string, options?: { schemaUrl?: string }): Tracer {\n const key = `${name}@${version || ''}:${options?.schemaUrl || ''}`;\n if (!this._tracers.has(key)) {\n this._tracers.set(key, new SentryCloudflareTracer());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this._tracers.get(key)!;\n }\n}\n\nclass SentryCloudflareTracer implements Tracer {\n public startSpan(name: string, options?: SpanOptions): Span {\n return startInactiveSpan({\n name,\n ...options,\n attributes: {\n ...options?.attributes,\n 'sentry.cloudflare_tracer': true,\n },\n });\n }\n\n /**\n * NOTE: This does not handle `context` being passed in. It will always put spans on the current scope.\n */\n public startActiveSpan<F extends (span: Span) => unknown>(name: string, fn: F): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(name: string, options: SpanOptions, fn: F): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(\n name: string,\n options: SpanOptions,\n context: Context,\n fn: F,\n ): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(\n name: string,\n options: unknown,\n context?: unknown,\n fn?: F,\n ): ReturnType<F> {\n const opts = (typeof options === 'object' && options !== null ? options : {}) as SpanOptions;\n\n const spanOpts = {\n name,\n ...opts,\n attributes: {\n ...opts.attributes,\n 'sentry.cloudflare_tracer': true,\n },\n };\n\n const callback = (\n typeof options === 'function'\n ? options\n : typeof context === 'function'\n ? context\n : typeof fn === 'function'\n ? fn\n : () => {}\n ) as F;\n\n // In OTEL the semantic matches `startSpanManual` because spans are not auto-ended\n return startSpanManual(spanOpts, callback) as ReturnType<F>;\n }\n}\n"],"names":[],"mappings":";;;AAIA;AACA;AACA;AACA;AACO,SAAS,wBAAwB,GAAS;AACjD,EAAE,KAAK,CAAC,uBAAuB,CAAC,IAAI,6BAA6B,EAAE,CAAC;AACpE;;AAEA,MAAM,+BAAwD,CAAA,WAAA,GAAA,EAAA,6BAAA,CAAA,SAAA,CAAA,MAAA,CAAA,IAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AAC9D,mBAAmB,QAAQ,GAAwB,IAAI,GAAG,GAAC;;AAE3D,GAAS,SAAS,CAAC,IAAI,EAAU,OAAO,EAAW,OAAO,EAAmC;AAC7F,IAAI,MAAM,GAAA,GAAM,CAAC,EAAA,IAAA,CAAA,CAAA,EAAA,OAAA,IAAA,EAAA,CAAA,CAAA,EAAA,OAAA,EAAA,SAAA,IAAA,EAAA,CAAA,CAAA;AACA,IAAA,IAAA,CAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,CAAA,EAAA;AACA,MAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,EAAA,IAAA,sBAAA,EAAA,CAAA;AACA,IAAA;;AAEA;AACA,IAAA,OAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,CAAA;AACA,EAAA;AACA;;AAEA,MAAA,sBAAA,EAAA;AACA,GAAA,SAAA,CAAA,IAAA,EAAA,OAAA,EAAA;AACA,IAAA,OAAA,iBAAA,CAAA;AACA,MAAA,IAAA;AACA,MAAA,GAAA,OAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,GAAA,OAAA,EAAA,UAAA;AACA,QAAA,0BAAA,EAAA,IAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA,EAAA;;AAEA;AACA;AACA;;AASA,GAAA,eAAA;AACA,IAAA,IAAA;AACA,IAAA,OAAA;AACA,IAAA,OAAA;AACA,IAAA,EAAA;AACA,IAAA;AACA,IAAA,MAAA,IAAA,IAAA,OAAA,OAAA,KAAA,QAAA,IAAA,OAAA,KAAA,IAAA,GAAA,OAAA,GAAA,EAAA,CAAA;;AAEA,IAAA,MAAA,QAAA,GAAA;AACA,MAAA,IAAA;AACA,MAAA,GAAA,IAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,GAAA,IAAA,CAAA,UAAA;AACA,QAAA,0BAAA,EAAA,IAAA;AACA,OAAA;AACA,KAAA;;AAEA,IAAA,MAAA,QAAA;AACA,MAAA,OAAA,OAAA,KAAA;AACA,UAAA;AACA,UAAA,OAAA,OAAA,KAAA;AACA,YAAA;AACA,YAAA,OAAA,EAAA,KAAA;AACA,cAAA;AACA,cAAA,MAAA,CAAA;AACA,KAAA;;AAEA;AACA,IAAA,OAAA,eAAA,CAAA,QAAA,EAAA,QAAA,CAAA;AACA,EAAA;AACA;;;;"}
1
+ {"version":3,"file":"tracer.js","sources":["../../../src/opentelemetry/tracer.ts"],"sourcesContent":["import type { Context, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';\nimport { trace } from '@opentelemetry/api';\nimport { startInactiveSpan, startSpanManual } from '@sentry/core';\n\n/**\n * Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans.\n * This is not perfect but handles easy/common use cases.\n */\nexport function setupOpenTelemetryTracer(): void {\n trace.setGlobalTracerProvider(new SentryCloudflareTraceProvider());\n}\n\nclass SentryCloudflareTraceProvider implements TracerProvider {\n private readonly _tracers: Map<string, Tracer> = new Map();\n\n public getTracer(name: string, version?: string, options?: { schemaUrl?: string }): Tracer {\n const key = `${name}@${version || ''}:${options?.schemaUrl || ''}`;\n if (!this._tracers.has(key)) {\n this._tracers.set(key, new SentryCloudflareTracer());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this._tracers.get(key)!;\n }\n}\n\nclass SentryCloudflareTracer implements Tracer {\n public startSpan(name: string, options?: SpanOptions): Span {\n return startInactiveSpan({\n ...options,\n name,\n attributes: {\n ...options?.attributes,\n 'sentry.cloudflare_tracer': true,\n },\n });\n }\n\n /**\n * NOTE: This does not handle `context` being passed in. It will always put spans on the current scope.\n */\n public startActiveSpan<F extends (span: Span) => unknown>(name: string, fn: F): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(name: string, options: SpanOptions, fn: F): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(\n name: string,\n options: SpanOptions,\n context: Context,\n fn: F,\n ): ReturnType<F>;\n public startActiveSpan<F extends (span: Span) => unknown>(\n name: string,\n options: unknown,\n context?: unknown,\n fn?: F,\n ): ReturnType<F> {\n const opts = (typeof options === 'object' && options !== null ? options : {}) as SpanOptions;\n\n const spanOpts = {\n ...opts,\n name,\n attributes: {\n ...opts.attributes,\n 'sentry.cloudflare_tracer': true,\n },\n };\n\n const callback = (\n typeof options === 'function'\n ? options\n : typeof context === 'function'\n ? context\n : typeof fn === 'function'\n ? fn\n : () => {}\n ) as F;\n\n // In OTEL the semantic matches `startSpanManual` because spans are not auto-ended\n return startSpanManual(spanOpts, callback) as ReturnType<F>;\n }\n}\n"],"names":[],"mappings":";;;AAIA;AACA;AACA;AACA;AACO,SAAS,wBAAwB,GAAS;AACjD,EAAE,KAAK,CAAC,uBAAuB,CAAC,IAAI,6BAA6B,EAAE,CAAC;AACpE;;AAEA,MAAM,+BAAwD,CAAA,WAAA,GAAA,EAAA,6BAAA,CAAA,SAAA,CAAA,MAAA,CAAA,IAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AAC9D,mBAAmB,QAAQ,GAAwB,IAAI,GAAG,GAAC;;AAE3D,GAAS,SAAS,CAAC,IAAI,EAAU,OAAO,EAAW,OAAO,EAAmC;AAC7F,IAAI,MAAM,GAAA,GAAM,CAAC,EAAA,IAAA,CAAA,CAAA,EAAA,OAAA,IAAA,EAAA,CAAA,CAAA,EAAA,OAAA,EAAA,SAAA,IAAA,EAAA,CAAA,CAAA;AACA,IAAA,IAAA,CAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,CAAA,EAAA;AACA,MAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,EAAA,IAAA,sBAAA,EAAA,CAAA;AACA,IAAA;;AAEA;AACA,IAAA,OAAA,IAAA,CAAA,QAAA,CAAA,GAAA,CAAA,GAAA,CAAA;AACA,EAAA;AACA;;AAEA,MAAA,sBAAA,EAAA;AACA,GAAA,SAAA,CAAA,IAAA,EAAA,OAAA,EAAA;AACA,IAAA,OAAA,iBAAA,CAAA;AACA,MAAA,GAAA,OAAA;AACA,MAAA,IAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,GAAA,OAAA,EAAA,UAAA;AACA,QAAA,0BAAA,EAAA,IAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA,EAAA;;AAEA;AACA;AACA;;AASA,GAAA,eAAA;AACA,IAAA,IAAA;AACA,IAAA,OAAA;AACA,IAAA,OAAA;AACA,IAAA,EAAA;AACA,IAAA;AACA,IAAA,MAAA,IAAA,IAAA,OAAA,OAAA,KAAA,QAAA,IAAA,OAAA,KAAA,IAAA,GAAA,OAAA,GAAA,EAAA,CAAA;;AAEA,IAAA,MAAA,QAAA,GAAA;AACA,MAAA,GAAA,IAAA;AACA,MAAA,IAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,GAAA,IAAA,CAAA,UAAA;AACA,QAAA,0BAAA,EAAA,IAAA;AACA,OAAA;AACA,KAAA;;AAEA,IAAA,MAAA,QAAA;AACA,MAAA,OAAA,OAAA,KAAA;AACA,UAAA;AACA,UAAA,OAAA,OAAA,KAAA;AACA,YAAA;AACA,YAAA,OAAA,EAAA,KAAA;AACA,cAAA;AACA,cAAA,MAAA,CAAA;AACA,KAAA;;AAEA;AACA,IAAA,OAAA,eAAA,CAAA,QAAA,EAAA,QAAA,CAAA;AACA,EAAA;AACA;;;;"}
@@ -1 +1 @@
1
- {"type":"module","version":"10.32.1","sideEffects":false}
1
+ {"type":"module","version":"10.34.0","sideEffects":false}
@@ -76,7 +76,18 @@ function makeCloudflareTransport(options) {
76
76
  };
77
77
 
78
78
  return suppressTracing(() => {
79
- return (options.fetch ?? fetch)(options.url, requestOptions).then(response => {
79
+ return (options.fetch ?? fetch)(options.url, requestOptions).then(async response => {
80
+ // Consume the response body to satisfy Cloudflare Workers' fetch requirements.
81
+ // The runtime requires all fetch response bodies to be read or explicitly canceled
82
+ // to prevent connection stalls and potential deadlocks. We read the body as text
83
+ // even though we don't use the content, as Sentry's response information is in the headers.
84
+ // See: https://github.com/getsentry/sentry-javascript/issues/18534
85
+ try {
86
+ await response.text();
87
+ } catch {
88
+ // no-op
89
+ }
90
+
80
91
  return {
81
92
  statusCode: response.status,
82
93
  headers: {
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sources":["../../src/transport.ts"],"sourcesContent":["import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core';\nimport { createTransport, SENTRY_BUFFER_FULL_ERROR, suppressTracing } from '@sentry/core';\n\nexport interface CloudflareTransportOptions extends BaseTransportOptions {\n /** Custom fetch function to use. This allows usage of things like Workers VPC */\n fetch?: typeof fetch;\n /** Fetch API init parameters. */\n fetchOptions?: RequestInit;\n}\n\nconst DEFAULT_TRANSPORT_BUFFER_SIZE = 30;\n\n/**\n * This is a modified promise buffer that collects tasks until drain is called.\n * We need this in the edge runtime because edge function invocations may not share I/O objects, like fetch requests\n * and responses, and the normal PromiseBuffer inherently buffers stuff inbetween incoming requests.\n *\n * A limitation we need to be aware of is that DEFAULT_TRANSPORT_BUFFER_SIZE is the maximum amount of payloads the\n * SDK can send for a given edge function invocation.\n */\nexport class IsolatedPromiseBuffer {\n // We just have this field because the promise buffer interface requires it.\n // If we ever remove it from the interface we should also remove it here.\n public $: Array<PromiseLike<TransportMakeRequestResponse>>;\n\n private _taskProducers: (() => PromiseLike<TransportMakeRequestResponse>)[];\n\n private readonly _bufferSize: number;\n\n public constructor(_bufferSize = DEFAULT_TRANSPORT_BUFFER_SIZE) {\n this.$ = [];\n this._taskProducers = [];\n this._bufferSize = _bufferSize;\n }\n\n /**\n * @inheritdoc\n */\n public add(taskProducer: () => PromiseLike<TransportMakeRequestResponse>): PromiseLike<TransportMakeRequestResponse> {\n if (this._taskProducers.length >= this._bufferSize) {\n return Promise.reject(SENTRY_BUFFER_FULL_ERROR);\n }\n\n this._taskProducers.push(taskProducer);\n return Promise.resolve({});\n }\n\n /**\n * @inheritdoc\n */\n public drain(timeout?: number): PromiseLike<boolean> {\n const oldTaskProducers = [...this._taskProducers];\n this._taskProducers = [];\n\n return new Promise(resolve => {\n const timer = setTimeout(() => {\n if (timeout && timeout > 0) {\n resolve(false);\n }\n }, timeout);\n\n // This cannot reject\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n Promise.all(\n oldTaskProducers.map(taskProducer =>\n taskProducer().then(null, () => {\n // catch all failed requests\n }),\n ),\n ).then(() => {\n // resolve to true if all fetch requests settled\n clearTimeout(timer);\n resolve(true);\n });\n });\n }\n}\n\n/**\n * Creates a Transport that uses the native fetch API to send events to Sentry.\n */\nexport function makeCloudflareTransport(options: CloudflareTransportOptions): Transport {\n function makeRequest(request: TransportRequest): PromiseLike<TransportMakeRequestResponse> {\n const requestOptions: RequestInit = {\n body: request.body,\n method: 'POST',\n headers: options.headers,\n ...options.fetchOptions,\n };\n\n return suppressTracing(() => {\n return (options.fetch ?? fetch)(options.url, requestOptions).then(response => {\n return {\n statusCode: response.status,\n headers: {\n 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),\n 'retry-after': response.headers.get('Retry-After'),\n },\n };\n });\n });\n }\n\n return createTransport(options, makeRequest, new IsolatedPromiseBuffer(options.bufferSize));\n}\n"],"names":[],"mappings":";;AAUA,MAAM,6BAAA,GAAgC,EAAE;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,qBAAA,CAAsB;AACnC;AACA;;AAOA,GAAS,WAAW,CAAC,WAAA,GAAc,6BAA6B,EAAE;AAClE,IAAI,IAAI,CAAC,CAAA,GAAI,EAAE;AACf,IAAI,IAAI,CAAC,cAAA,GAAiB,EAAE;AAC5B,IAAI,IAAI,CAAC,WAAA,GAAc,WAAW;AAClC,EAAE;;AAEF;AACA;AACA;AACA,GAAS,GAAG,CAAC,YAAY,EAA8F;AACvH,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,MAAA,IAAU,IAAI,CAAC,WAAW,EAAE;AACxD,MAAM,OAAO,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAC;AACrD,IAAI;;AAEJ,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;AAC1C,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;AAC9B,EAAE;;AAEF;AACA;AACA;AACA,GAAS,KAAK,CAAC,OAAO,EAAiC;AACvD,IAAI,MAAM,mBAAmB,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;AACrD,IAAI,IAAI,CAAC,cAAA,GAAiB,EAAE;;AAE5B,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW;AAClC,MAAM,MAAM,KAAA,GAAQ,UAAU,CAAC,MAAM;AACrC,QAAQ,IAAI,OAAA,IAAW,OAAA,GAAU,CAAC,EAAE;AACpC,UAAU,OAAO,CAAC,KAAK,CAAC;AACxB,QAAQ;AACR,MAAM,CAAC,EAAE,OAAO,CAAC;;AAEjB;AACA;AACA,MAAM,OAAO,CAAC,GAAG;AACjB,QAAQ,gBAAgB,CAAC,GAAG,CAAC,YAAA;AAC7B,UAAU,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;AAC1C;AACA,UAAU,CAAC,CAAC;AACZ,SAAS;AACT,OAAO,CAAC,IAAI,CAAC,MAAM;AACnB;AACA,QAAQ,YAAY,CAAC,KAAK,CAAC;AAC3B,QAAQ,OAAO,CAAC,IAAI,CAAC;AACrB,MAAM,CAAC,CAAC;AACR,IAAI,CAAC,CAAC;AACN,EAAE;AACF;;AAEA;AACA;AACA;AACO,SAAS,uBAAuB,CAAC,OAAO,EAAyC;AACxF,EAAE,SAAS,WAAW,CAAC,OAAO,EAA+D;AAC7F,IAAI,MAAM,cAAc,GAAgB;AACxC,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI;AACxB,MAAM,MAAM,EAAE,MAAM;AACpB,MAAM,OAAO,EAAE,OAAO,CAAC,OAAO;AAC9B,MAAM,GAAG,OAAO,CAAC,YAAY;AAC7B,KAAK;;AAEL,IAAI,OAAO,eAAe,CAAC,MAAM;AACjC,MAAM,OAAO,CAAC,OAAO,CAAC,KAAA,IAAS,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,YAAY;AACpF,QAAQ,OAAO;AACf,UAAU,UAAU,EAAE,QAAQ,CAAC,MAAM;AACrC,UAAU,OAAO,EAAE;AACnB,YAAY,sBAAsB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;AAChF,YAAY,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;AAC9D,WAAW;AACX,SAAS;AACT,MAAM,CAAC,CAAC;AACR,IAAI,CAAC,CAAC;AACN,EAAE;;AAEF,EAAE,OAAO,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC7F;;;;"}
1
+ {"version":3,"file":"transport.js","sources":["../../src/transport.ts"],"sourcesContent":["import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core';\nimport { createTransport, SENTRY_BUFFER_FULL_ERROR, suppressTracing } from '@sentry/core';\n\nexport interface CloudflareTransportOptions extends BaseTransportOptions {\n /** Custom fetch function to use. This allows usage of things like Workers VPC */\n fetch?: typeof fetch;\n /** Fetch API init parameters. */\n fetchOptions?: RequestInit;\n}\n\nconst DEFAULT_TRANSPORT_BUFFER_SIZE = 30;\n\n/**\n * This is a modified promise buffer that collects tasks until drain is called.\n * We need this in the edge runtime because edge function invocations may not share I/O objects, like fetch requests\n * and responses, and the normal PromiseBuffer inherently buffers stuff inbetween incoming requests.\n *\n * A limitation we need to be aware of is that DEFAULT_TRANSPORT_BUFFER_SIZE is the maximum amount of payloads the\n * SDK can send for a given edge function invocation.\n */\nexport class IsolatedPromiseBuffer {\n // We just have this field because the promise buffer interface requires it.\n // If we ever remove it from the interface we should also remove it here.\n public $: Array<PromiseLike<TransportMakeRequestResponse>>;\n\n private _taskProducers: (() => PromiseLike<TransportMakeRequestResponse>)[];\n\n private readonly _bufferSize: number;\n\n public constructor(_bufferSize = DEFAULT_TRANSPORT_BUFFER_SIZE) {\n this.$ = [];\n this._taskProducers = [];\n this._bufferSize = _bufferSize;\n }\n\n /**\n * @inheritdoc\n */\n public add(taskProducer: () => PromiseLike<TransportMakeRequestResponse>): PromiseLike<TransportMakeRequestResponse> {\n if (this._taskProducers.length >= this._bufferSize) {\n return Promise.reject(SENTRY_BUFFER_FULL_ERROR);\n }\n\n this._taskProducers.push(taskProducer);\n return Promise.resolve({});\n }\n\n /**\n * @inheritdoc\n */\n public drain(timeout?: number): PromiseLike<boolean> {\n const oldTaskProducers = [...this._taskProducers];\n this._taskProducers = [];\n\n return new Promise(resolve => {\n const timer = setTimeout(() => {\n if (timeout && timeout > 0) {\n resolve(false);\n }\n }, timeout);\n\n // This cannot reject\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n Promise.all(\n oldTaskProducers.map(taskProducer =>\n taskProducer().then(null, () => {\n // catch all failed requests\n }),\n ),\n ).then(() => {\n // resolve to true if all fetch requests settled\n clearTimeout(timer);\n resolve(true);\n });\n });\n }\n}\n\n/**\n * Creates a Transport that uses the native fetch API to send events to Sentry.\n */\nexport function makeCloudflareTransport(options: CloudflareTransportOptions): Transport {\n function makeRequest(request: TransportRequest): PromiseLike<TransportMakeRequestResponse> {\n const requestOptions: RequestInit = {\n body: request.body,\n method: 'POST',\n headers: options.headers,\n ...options.fetchOptions,\n };\n\n return suppressTracing(() => {\n return (options.fetch ?? fetch)(options.url, requestOptions).then(async response => {\n // Consume the response body to satisfy Cloudflare Workers' fetch requirements.\n // The runtime requires all fetch response bodies to be read or explicitly canceled\n // to prevent connection stalls and potential deadlocks. We read the body as text\n // even though we don't use the content, as Sentry's response information is in the headers.\n // See: https://github.com/getsentry/sentry-javascript/issues/18534\n try {\n await response.text();\n } catch {\n // no-op\n }\n\n return {\n statusCode: response.status,\n headers: {\n 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),\n 'retry-after': response.headers.get('Retry-After'),\n },\n };\n });\n });\n }\n\n return createTransport(options, makeRequest, new IsolatedPromiseBuffer(options.bufferSize));\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/integrations/fetch.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,OAAO;IACtB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,0BAA0B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACvD;AA+ED;;GAEG;AACH,eAAO,MAAM,gBAAgB,gFAAuC,CAAC"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/integrations/fetch.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,OAAO;IACtB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,0BAA0B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACvD;AAiFD;;GAEG;AACH,eAAO,MAAM,gBAAgB,gFAAuC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,4BAA4B,EAAoB,MAAM,cAAc,CAAC;AAGpH,MAAM,WAAW,0BAA2B,SAAQ,oBAAoB;IACtE,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,iCAAiC;IACjC,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B;AAID;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAGzB,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC,CAAC;IAE3D,OAAO,CAAC,cAAc,CAAsD;IAE5E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAElB,WAAW,SAAgC;IAM9D;;OAEG;IACI,GAAG,CAAC,YAAY,EAAE,MAAM,WAAW,CAAC,4BAA4B,CAAC,GAAG,WAAW,CAAC,4BAA4B,CAAC;IASpH;;OAEG;IACI,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC;CA0BrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,0BAA0B,GAAG,SAAS,CAuBtF"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,4BAA4B,EAAoB,MAAM,cAAc,CAAC;AAGpH,MAAM,WAAW,0BAA2B,SAAQ,oBAAoB;IACtE,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,iCAAiC;IACjC,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B;AAID;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAGzB,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC,CAAC;IAE3D,OAAO,CAAC,cAAc,CAAsD;IAE5E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAElB,WAAW,SAAgC;IAM9D;;OAEG;IACI,GAAG,CAAC,YAAY,EAAE,MAAM,WAAW,CAAC,4BAA4B,CAAC,GAAG,WAAW,CAAC,4BAA4B,CAAC;IASpH;;OAEG;IACI,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC;CA0BrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,0BAA0B,GAAG,SAAS,CAkCtF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/cloudflare",
3
- "version": "10.32.1",
3
+ "version": "10.34.0",
4
4
  "description": "Official Sentry SDK for Cloudflare Workers and Pages",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/cloudflare",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@opentelemetry/api": "^1.9.0",
53
- "@sentry/core": "10.32.1"
53
+ "@sentry/core": "10.34.0"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@cloudflare/workers-types": "^4.x"
@@ -1,3 +0,0 @@
1
- /** Detect CommonJS. */
2
- export declare function isCjs(): boolean;
3
- //# sourceMappingURL=commonjs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"commonjs.d.ts","sourceRoot":"","sources":["../../../src/utils/commonjs.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,wBAAgB,KAAK,IAAI,OAAO,CAM/B"}
@@ -1,3 +0,0 @@
1
- /** Detect CommonJS. */
2
- export declare function isCjs(): boolean;
3
- //# sourceMappingURL=commonjs.d.ts.map