@sentry/cloudflare 11.0.0-alpha.1 → 11.0.0-beta.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/dev/baseSdk.js +20 -8
- package/build/cjs/dev/baseSdk.js.map +1 -1
- package/build/cjs/dev/client.js +118 -25
- package/build/cjs/dev/client.js.map +1 -1
- package/build/cjs/dev/clientCache.js +15 -0
- package/build/cjs/dev/clientCache.js.map +1 -0
- package/build/cjs/dev/defineCloudflareOptions.js.map +1 -1
- package/build/cjs/dev/durableobject.js +4 -62
- package/build/cjs/dev/durableobject.js.map +1 -1
- package/build/cjs/dev/flush.js +6 -4
- package/build/cjs/dev/flush.js.map +1 -1
- package/build/cjs/dev/index.js +8 -7
- package/build/cjs/dev/index.js.map +1 -1
- package/build/cjs/dev/instrumentations/agents/instrumentAgentCallableRpc.js +3 -1
- package/build/cjs/dev/instrumentations/agents/instrumentAgentCallableRpc.js.map +1 -1
- package/build/cjs/dev/instrumentations/instrumentDurableObjectHandlers.js +123 -0
- package/build/cjs/dev/instrumentations/instrumentDurableObjectHandlers.js.map +1 -0
- package/build/cjs/dev/instrumentations/instrumentDurableObjectNamespace.js +4 -4
- package/build/cjs/dev/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/cjs/dev/instrumentations/instrumentDurableObjectStorage.js +3 -1
- package/build/cjs/dev/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
- package/build/cjs/dev/instrumentations/instrumentDurableObjectSyncKvStorage.js +3 -1
- package/build/cjs/dev/instrumentations/instrumentDurableObjectSyncKvStorage.js.map +1 -1
- package/build/cjs/dev/instrumentations/instrumentSqlStorage.js +6 -3
- package/build/cjs/dev/instrumentations/instrumentSqlStorage.js.map +1 -1
- package/build/cjs/dev/instrumentations/instrumentWorkerEntrypoint.js +9 -16
- package/build/cjs/dev/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentD1.js +10 -3
- package/build/cjs/dev/instrumentations/worker/instrumentD1.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentEmail.js +4 -2
- package/build/cjs/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentEnv.js +5 -12
- package/build/cjs/dev/instrumentations/worker/instrumentEnv.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentFetch.js +8 -8
- package/build/cjs/dev/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentQueue.js +4 -2
- package/build/cjs/dev/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentQueueProducer.js +3 -2
- package/build/cjs/dev/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentR2.js +21 -18
- package/build/cjs/dev/instrumentations/worker/instrumentR2.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js +4 -2
- package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/cjs/dev/instrumentations/worker/instrumentTail.js +2 -0
- package/build/cjs/dev/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/cjs/dev/integrations/fetch.js +1 -11
- package/build/cjs/dev/integrations/fetch.js.map +1 -1
- package/build/cjs/dev/opentelemetry/tracer.js +2 -40
- package/build/cjs/dev/opentelemetry/tracer.js.map +1 -1
- package/build/cjs/dev/pages-plugin.js +2 -2
- package/build/cjs/dev/pages-plugin.js.map +1 -1
- package/build/cjs/dev/request.js +2 -123
- package/build/cjs/dev/request.js.map +1 -1
- package/build/cjs/dev/sdk.js +11 -6
- package/build/cjs/dev/sdk.js.map +1 -1
- package/build/cjs/dev/transport.js +1 -1
- package/build/cjs/dev/transport.js.map +1 -1
- package/build/cjs/dev/utils/invocationContext.js +41 -0
- package/build/cjs/dev/utils/invocationContext.js.map +1 -0
- package/build/cjs/dev/utils/invocationScope.js +7 -2
- package/build/cjs/dev/utils/invocationScope.js.map +1 -1
- package/build/cjs/dev/utils/isBinding.js +0 -4
- package/build/cjs/dev/utils/isBinding.js.map +1 -1
- package/build/cjs/dev/utils/rpcPropagation.js +15 -0
- package/build/cjs/dev/utils/rpcPropagation.js.map +1 -0
- package/build/cjs/dev/vendor/stacktrace.js +2 -1
- package/build/cjs/dev/vendor/stacktrace.js.map +1 -1
- package/build/cjs/dev/vite/autoInstrument.js +2 -1
- package/build/cjs/dev/vite/autoInstrument.js.map +1 -1
- package/build/cjs/dev/vite/index.js.map +1 -1
- package/build/cjs/dev/vite/transform.js +30 -5
- package/build/cjs/dev/vite/transform.js.map +1 -1
- package/build/cjs/dev/vite/wranglerConfig.js +21 -1
- package/build/cjs/dev/vite/wranglerConfig.js.map +1 -1
- package/build/cjs/dev/withSentry.js.map +1 -1
- package/build/cjs/dev/workflows.js +45 -33
- package/build/cjs/dev/workflows.js.map +1 -1
- package/build/cjs/dev/wrapMethodWithSentry.js +51 -15
- package/build/cjs/dev/wrapMethodWithSentry.js.map +1 -1
- package/build/cjs/dev/wrapRequestHandlerWithInit.js +134 -0
- package/build/cjs/dev/wrapRequestHandlerWithInit.js.map +1 -0
- package/build/cjs/prod/baseSdk.js +20 -8
- package/build/cjs/prod/baseSdk.js.map +1 -1
- package/build/cjs/prod/client.js +118 -25
- package/build/cjs/prod/client.js.map +1 -1
- package/build/cjs/prod/clientCache.js +15 -0
- package/build/cjs/prod/clientCache.js.map +1 -0
- package/build/cjs/prod/defineCloudflareOptions.js.map +1 -1
- package/build/cjs/prod/durableobject.js +4 -62
- package/build/cjs/prod/durableobject.js.map +1 -1
- package/build/cjs/prod/flush.js +6 -4
- package/build/cjs/prod/flush.js.map +1 -1
- package/build/cjs/prod/index.js +8 -7
- package/build/cjs/prod/index.js.map +1 -1
- package/build/cjs/prod/instrumentations/agents/instrumentAgentCallableRpc.js +3 -1
- package/build/cjs/prod/instrumentations/agents/instrumentAgentCallableRpc.js.map +1 -1
- package/build/cjs/prod/instrumentations/instrumentDurableObjectHandlers.js +123 -0
- package/build/cjs/prod/instrumentations/instrumentDurableObjectHandlers.js.map +1 -0
- package/build/cjs/prod/instrumentations/instrumentDurableObjectNamespace.js +4 -4
- package/build/cjs/prod/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/cjs/prod/instrumentations/instrumentDurableObjectStorage.js +3 -1
- package/build/cjs/prod/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
- package/build/cjs/prod/instrumentations/instrumentDurableObjectSyncKvStorage.js +3 -1
- package/build/cjs/prod/instrumentations/instrumentDurableObjectSyncKvStorage.js.map +1 -1
- package/build/cjs/prod/instrumentations/instrumentSqlStorage.js +6 -3
- package/build/cjs/prod/instrumentations/instrumentSqlStorage.js.map +1 -1
- package/build/cjs/prod/instrumentations/instrumentWorkerEntrypoint.js +9 -16
- package/build/cjs/prod/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentD1.js +10 -3
- package/build/cjs/prod/instrumentations/worker/instrumentD1.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentEmail.js +4 -2
- package/build/cjs/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentEnv.js +5 -12
- package/build/cjs/prod/instrumentations/worker/instrumentEnv.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentFetch.js +8 -8
- package/build/cjs/prod/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentQueue.js +4 -2
- package/build/cjs/prod/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentQueueProducer.js +3 -2
- package/build/cjs/prod/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentR2.js +21 -18
- package/build/cjs/prod/instrumentations/worker/instrumentR2.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js +4 -2
- package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/cjs/prod/instrumentations/worker/instrumentTail.js +2 -0
- package/build/cjs/prod/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/cjs/prod/integrations/fetch.js +1 -11
- package/build/cjs/prod/integrations/fetch.js.map +1 -1
- package/build/cjs/prod/opentelemetry/tracer.js +2 -40
- package/build/cjs/prod/opentelemetry/tracer.js.map +1 -1
- package/build/cjs/prod/pages-plugin.js +2 -2
- package/build/cjs/prod/pages-plugin.js.map +1 -1
- package/build/cjs/prod/request.js +2 -123
- package/build/cjs/prod/request.js.map +1 -1
- package/build/cjs/prod/sdk.js +11 -6
- package/build/cjs/prod/sdk.js.map +1 -1
- package/build/cjs/prod/transport.js +1 -1
- package/build/cjs/prod/transport.js.map +1 -1
- package/build/cjs/prod/utils/invocationContext.js +41 -0
- package/build/cjs/prod/utils/invocationContext.js.map +1 -0
- package/build/cjs/prod/utils/invocationScope.js +7 -2
- package/build/cjs/prod/utils/invocationScope.js.map +1 -1
- package/build/cjs/prod/utils/isBinding.js +0 -4
- package/build/cjs/prod/utils/isBinding.js.map +1 -1
- package/build/cjs/prod/utils/rpcPropagation.js +15 -0
- package/build/cjs/prod/utils/rpcPropagation.js.map +1 -0
- package/build/cjs/prod/vendor/stacktrace.js +2 -1
- package/build/cjs/prod/vendor/stacktrace.js.map +1 -1
- package/build/cjs/prod/vite/autoInstrument.js +2 -1
- package/build/cjs/prod/vite/autoInstrument.js.map +1 -1
- package/build/cjs/prod/vite/index.js.map +1 -1
- package/build/cjs/prod/vite/transform.js +30 -5
- package/build/cjs/prod/vite/transform.js.map +1 -1
- package/build/cjs/prod/vite/wranglerConfig.js +21 -1
- package/build/cjs/prod/vite/wranglerConfig.js.map +1 -1
- package/build/cjs/prod/withSentry.js.map +1 -1
- package/build/cjs/prod/workflows.js +45 -33
- package/build/cjs/prod/workflows.js.map +1 -1
- package/build/cjs/prod/wrapMethodWithSentry.js +51 -15
- package/build/cjs/prod/wrapMethodWithSentry.js.map +1 -1
- package/build/cjs/prod/wrapRequestHandlerWithInit.js +134 -0
- package/build/cjs/prod/wrapRequestHandlerWithInit.js.map +1 -0
- package/build/esm/dev/baseSdk.js +21 -9
- package/build/esm/dev/baseSdk.js.map +1 -1
- package/build/esm/dev/client.js +118 -25
- package/build/esm/dev/client.js.map +1 -1
- package/build/esm/dev/clientCache.js +12 -0
- package/build/esm/dev/clientCache.js.map +1 -0
- package/build/esm/dev/defineCloudflareOptions.js.map +1 -1
- package/build/esm/dev/durableobject.js +5 -63
- package/build/esm/dev/durableobject.js.map +1 -1
- package/build/esm/dev/flush.js +6 -4
- package/build/esm/dev/flush.js.map +1 -1
- package/build/esm/dev/index.js +4 -4
- package/build/esm/dev/instrumentations/agents/instrumentAgentCallableRpc.js +4 -2
- package/build/esm/dev/instrumentations/agents/instrumentAgentCallableRpc.js.map +1 -1
- package/build/esm/dev/instrumentations/instrumentDurableObjectHandlers.js +121 -0
- package/build/esm/dev/instrumentations/instrumentDurableObjectHandlers.js.map +1 -0
- package/build/esm/dev/instrumentations/instrumentDurableObjectNamespace.js +4 -4
- package/build/esm/dev/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/esm/dev/instrumentations/instrumentDurableObjectStorage.js +3 -1
- package/build/esm/dev/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
- package/build/esm/dev/instrumentations/instrumentDurableObjectSyncKvStorage.js +3 -1
- package/build/esm/dev/instrumentations/instrumentDurableObjectSyncKvStorage.js.map +1 -1
- package/build/esm/dev/instrumentations/instrumentSqlStorage.js +5 -2
- package/build/esm/dev/instrumentations/instrumentSqlStorage.js.map +1 -1
- package/build/esm/dev/instrumentations/instrumentWorkerEntrypoint.js +9 -16
- package/build/esm/dev/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentD1.js +11 -4
- package/build/esm/dev/instrumentations/worker/instrumentD1.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentEmail.js +7 -5
- package/build/esm/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentEnv.js +6 -13
- package/build/esm/dev/instrumentations/worker/instrumentEnv.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentFetch.js +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentQueue.js +7 -5
- package/build/esm/dev/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentQueueProducer.js +4 -3
- package/build/esm/dev/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentR2.js +22 -19
- package/build/esm/dev/instrumentations/worker/instrumentR2.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentScheduled.js +7 -5
- package/build/esm/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/esm/dev/instrumentations/worker/instrumentTail.js +2 -0
- package/build/esm/dev/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/esm/dev/integrations/fetch.js +2 -12
- package/build/esm/dev/integrations/fetch.js.map +1 -1
- package/build/esm/dev/opentelemetry/tracer.js +2 -40
- package/build/esm/dev/opentelemetry/tracer.js.map +1 -1
- package/build/esm/dev/package.json +1 -1
- package/build/esm/dev/pages-plugin.js +1 -1
- package/build/esm/dev/pages-plugin.js.map +1 -1
- package/build/esm/dev/request.js +2 -122
- package/build/esm/dev/request.js.map +1 -1
- package/build/esm/dev/sdk.js +11 -7
- package/build/esm/dev/sdk.js.map +1 -1
- package/build/esm/dev/transport.js +1 -1
- package/build/esm/dev/transport.js.map +1 -1
- package/build/esm/dev/utils/invocationContext.js +37 -0
- package/build/esm/dev/utils/invocationContext.js.map +1 -0
- package/build/esm/dev/utils/invocationScope.js +7 -2
- package/build/esm/dev/utils/invocationScope.js.map +1 -1
- package/build/esm/dev/utils/isBinding.js +1 -4
- package/build/esm/dev/utils/isBinding.js.map +1 -1
- package/build/esm/dev/utils/rpcPropagation.js +13 -0
- package/build/esm/dev/utils/rpcPropagation.js.map +1 -0
- package/build/esm/dev/utils/traceLinks.js +1 -1
- package/build/esm/dev/vendor/stacktrace.js +2 -1
- package/build/esm/dev/vendor/stacktrace.js.map +1 -1
- package/build/esm/dev/vite/autoInstrument.js +2 -1
- package/build/esm/dev/vite/autoInstrument.js.map +1 -1
- package/build/esm/dev/vite/index.js.map +1 -1
- package/build/esm/dev/vite/transform.js +30 -5
- package/build/esm/dev/vite/transform.js.map +1 -1
- package/build/esm/dev/vite/wranglerConfig.js +21 -2
- package/build/esm/dev/vite/wranglerConfig.js.map +1 -1
- package/build/esm/dev/withSentry.js.map +1 -1
- package/build/esm/dev/workflows.js +48 -36
- package/build/esm/dev/workflows.js.map +1 -1
- package/build/esm/dev/wrapMethodWithSentry.js +53 -17
- package/build/esm/dev/wrapMethodWithSentry.js.map +1 -1
- package/build/esm/dev/wrapRequestHandlerWithInit.js +132 -0
- package/build/esm/dev/wrapRequestHandlerWithInit.js.map +1 -0
- package/build/esm/prod/baseSdk.js +21 -9
- package/build/esm/prod/baseSdk.js.map +1 -1
- package/build/esm/prod/client.js +118 -25
- package/build/esm/prod/client.js.map +1 -1
- package/build/esm/prod/clientCache.js +12 -0
- package/build/esm/prod/clientCache.js.map +1 -0
- package/build/esm/prod/defineCloudflareOptions.js.map +1 -1
- package/build/esm/prod/durableobject.js +5 -63
- package/build/esm/prod/durableobject.js.map +1 -1
- package/build/esm/prod/flush.js +6 -4
- package/build/esm/prod/flush.js.map +1 -1
- package/build/esm/prod/index.js +4 -4
- package/build/esm/prod/instrumentations/agents/instrumentAgentCallableRpc.js +4 -2
- package/build/esm/prod/instrumentations/agents/instrumentAgentCallableRpc.js.map +1 -1
- package/build/esm/prod/instrumentations/instrumentDurableObjectHandlers.js +121 -0
- package/build/esm/prod/instrumentations/instrumentDurableObjectHandlers.js.map +1 -0
- package/build/esm/prod/instrumentations/instrumentDurableObjectNamespace.js +4 -4
- package/build/esm/prod/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/esm/prod/instrumentations/instrumentDurableObjectStorage.js +3 -1
- package/build/esm/prod/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
- package/build/esm/prod/instrumentations/instrumentDurableObjectSyncKvStorage.js +3 -1
- package/build/esm/prod/instrumentations/instrumentDurableObjectSyncKvStorage.js.map +1 -1
- package/build/esm/prod/instrumentations/instrumentSqlStorage.js +5 -2
- package/build/esm/prod/instrumentations/instrumentSqlStorage.js.map +1 -1
- package/build/esm/prod/instrumentations/instrumentWorkerEntrypoint.js +9 -16
- package/build/esm/prod/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentD1.js +11 -4
- package/build/esm/prod/instrumentations/worker/instrumentD1.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentEmail.js +7 -5
- package/build/esm/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentEnv.js +6 -13
- package/build/esm/prod/instrumentations/worker/instrumentEnv.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentFetch.js +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentQueue.js +7 -5
- package/build/esm/prod/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentQueueProducer.js +4 -3
- package/build/esm/prod/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentR2.js +22 -19
- package/build/esm/prod/instrumentations/worker/instrumentR2.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentScheduled.js +7 -5
- package/build/esm/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/esm/prod/instrumentations/worker/instrumentTail.js +2 -0
- package/build/esm/prod/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/esm/prod/integrations/fetch.js +2 -12
- package/build/esm/prod/integrations/fetch.js.map +1 -1
- package/build/esm/prod/opentelemetry/tracer.js +2 -40
- package/build/esm/prod/opentelemetry/tracer.js.map +1 -1
- package/build/esm/prod/package.json +1 -1
- package/build/esm/prod/pages-plugin.js +1 -1
- package/build/esm/prod/pages-plugin.js.map +1 -1
- package/build/esm/prod/request.js +2 -122
- package/build/esm/prod/request.js.map +1 -1
- package/build/esm/prod/sdk.js +11 -7
- package/build/esm/prod/sdk.js.map +1 -1
- package/build/esm/prod/transport.js +1 -1
- package/build/esm/prod/transport.js.map +1 -1
- package/build/esm/prod/utils/invocationContext.js +37 -0
- package/build/esm/prod/utils/invocationContext.js.map +1 -0
- package/build/esm/prod/utils/invocationScope.js +7 -2
- package/build/esm/prod/utils/invocationScope.js.map +1 -1
- package/build/esm/prod/utils/isBinding.js +1 -4
- package/build/esm/prod/utils/isBinding.js.map +1 -1
- package/build/esm/prod/utils/rpcPropagation.js +13 -0
- package/build/esm/prod/utils/rpcPropagation.js.map +1 -0
- package/build/esm/prod/utils/traceLinks.js +1 -1
- package/build/esm/prod/vendor/stacktrace.js +2 -1
- package/build/esm/prod/vendor/stacktrace.js.map +1 -1
- package/build/esm/prod/vite/autoInstrument.js +2 -1
- package/build/esm/prod/vite/autoInstrument.js.map +1 -1
- package/build/esm/prod/vite/index.js.map +1 -1
- package/build/esm/prod/vite/transform.js +30 -5
- package/build/esm/prod/vite/transform.js.map +1 -1
- package/build/esm/prod/vite/wranglerConfig.js +21 -2
- package/build/esm/prod/vite/wranglerConfig.js.map +1 -1
- package/build/esm/prod/withSentry.js.map +1 -1
- package/build/esm/prod/workflows.js +48 -36
- package/build/esm/prod/workflows.js.map +1 -1
- package/build/esm/prod/wrapMethodWithSentry.js +53 -17
- package/build/esm/prod/wrapMethodWithSentry.js.map +1 -1
- package/build/esm/prod/wrapRequestHandlerWithInit.js +132 -0
- package/build/esm/prod/wrapRequestHandlerWithInit.js.map +1 -0
- package/build/types/baseSdk.d.ts +8 -0
- package/build/types/baseSdk.d.ts.map +1 -1
- package/build/types/client.d.ts +91 -18
- package/build/types/client.d.ts.map +1 -1
- package/build/types/clientCache.d.ts +8 -0
- package/build/types/clientCache.d.ts.map +1 -0
- package/build/types/defineCloudflareOptions.d.ts +3 -2
- package/build/types/defineCloudflareOptions.d.ts.map +1 -1
- package/build/types/durableobject.d.ts +5 -7
- package/build/types/durableobject.d.ts.map +1 -1
- package/build/types/flush.d.ts +2 -0
- package/build/types/flush.d.ts.map +1 -1
- package/build/types/index.d.ts +4 -4
- package/build/types/index.d.ts.map +1 -1
- package/build/types/instrumentations/agents/instrumentAgentCallableRpc.d.ts.map +1 -1
- package/build/types/instrumentations/instrumentDurableObjectHandlers.d.ts +28 -0
- package/build/types/instrumentations/instrumentDurableObjectHandlers.d.ts.map +1 -0
- package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts +2 -1
- package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts.map +1 -1
- package/build/types/instrumentations/instrumentDurableObjectStorage.d.ts.map +1 -1
- package/build/types/instrumentations/instrumentDurableObjectSyncKvStorage.d.ts.map +1 -1
- package/build/types/instrumentations/instrumentSqlStorage.d.ts.map +1 -1
- package/build/types/instrumentations/instrumentWorkerEntrypoint.d.ts +2 -3
- package/build/types/instrumentations/instrumentWorkerEntrypoint.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentD1.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentEmail.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentEnv.d.ts +0 -1
- package/build/types/instrumentations/worker/instrumentEnv.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentQueue.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentQueueProducer.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentR2.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentScheduled.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentTail.d.ts.map +1 -1
- package/build/types/integrations/fetch.d.ts.map +1 -1
- package/build/types/opentelemetry/tracer.d.ts.map +1 -1
- package/build/types/pages-plugin.d.ts +3 -1
- package/build/types/pages-plugin.d.ts.map +1 -1
- package/build/types/request.d.ts +5 -31
- package/build/types/request.d.ts.map +1 -1
- package/build/types/sdk.d.ts +13 -4
- package/build/types/sdk.d.ts.map +1 -1
- package/build/types/transport.d.ts.map +1 -1
- package/build/types/types.d.ts +28 -0
- package/build/types/types.d.ts.map +1 -1
- package/build/types/utils/invocationContext.d.ts +58 -0
- package/build/types/utils/invocationContext.d.ts.map +1 -0
- package/build/types/utils/invocationScope.d.ts +2 -1
- package/build/types/utils/invocationScope.d.ts.map +1 -1
- package/build/types/utils/isBinding.d.ts +1 -9
- package/build/types/utils/isBinding.d.ts.map +1 -1
- package/build/types/utils/rpcPropagation.d.ts +10 -0
- package/build/types/utils/rpcPropagation.d.ts.map +1 -0
- package/build/types/vendor/stacktrace.d.ts.map +1 -1
- package/build/types/vite/autoInstrument.d.ts.map +1 -1
- package/build/types/vite/index.d.ts +4 -0
- package/build/types/vite/index.d.ts.map +1 -1
- package/build/types/vite/transform.d.ts +3 -0
- package/build/types/vite/transform.d.ts.map +1 -1
- package/build/types/vite/wranglerConfig.d.ts +13 -0
- package/build/types/vite/wranglerConfig.d.ts.map +1 -1
- package/build/types/withSentry.d.ts +2 -3
- package/build/types/withSentry.d.ts.map +1 -1
- package/build/types/workflows.d.ts +3 -3
- package/build/types/workflows.d.ts.map +1 -1
- package/build/types/wrapMethodWithSentry.d.ts +6 -1
- package/build/types/wrapMethodWithSentry.d.ts.map +1 -1
- package/build/types/wrapRequestHandlerWithInit.d.ts +31 -0
- package/build/types/wrapRequestHandlerWithInit.d.ts.map +1 -0
- package/package.json +6 -4
- package/build/cjs/dev/instrumentations/worker/instrumentRateLimit.js +0 -29
- package/build/cjs/dev/instrumentations/worker/instrumentRateLimit.js.map +0 -1
- package/build/cjs/dev/integrations/tracing/vercelai.js +0 -18
- package/build/cjs/dev/integrations/tracing/vercelai.js.map +0 -1
- package/build/cjs/prod/instrumentations/worker/instrumentRateLimit.js +0 -29
- package/build/cjs/prod/instrumentations/worker/instrumentRateLimit.js.map +0 -1
- package/build/cjs/prod/integrations/tracing/vercelai.js +0 -18
- package/build/cjs/prod/integrations/tracing/vercelai.js.map +0 -1
- package/build/esm/dev/instrumentations/worker/instrumentRateLimit.js +0 -27
- package/build/esm/dev/instrumentations/worker/instrumentRateLimit.js.map +0 -1
- package/build/esm/dev/integrations/tracing/vercelai.js +0 -16
- package/build/esm/dev/integrations/tracing/vercelai.js.map +0 -1
- package/build/esm/prod/instrumentations/worker/instrumentRateLimit.js +0 -27
- package/build/esm/prod/instrumentations/worker/instrumentRateLimit.js.map +0 -1
- package/build/esm/prod/integrations/tracing/vercelai.js +0 -16
- package/build/esm/prod/integrations/tracing/vercelai.js.map +0 -1
- package/build/types/instrumentations/worker/instrumentRateLimit.d.ts +0 -6
- package/build/types/instrumentations/worker/instrumentRateLimit.d.ts.map +0 -1
- package/build/types/integrations/tracing/vercelai.d.ts +0 -39
- package/build/types/integrations/tracing/vercelai.d.ts.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { isThenable, SEMANTIC_ATTRIBUTE_SENTRY_OP, continueTrace, startNewTrace, captureException, startSpan,
|
|
1
|
+
import { isThenable, SEMANTIC_ATTRIBUTE_SENTRY_OP, continueTrace, startNewTrace, isObjectLike, captureException, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';
|
|
2
2
|
import { getOriginalWaitUntil, flushAndDispose } from './flush.js';
|
|
3
3
|
import { ensureInstrumented } from './instrument.js';
|
|
4
4
|
import { init } from './sdk.js';
|
|
5
|
+
import { getInvocationState, getInvocationWaitUntil } from './utils/invocationContext.js';
|
|
5
6
|
import { withInvocationIsolationScope } from './utils/invocationScope.js';
|
|
6
7
|
import { extractRpcMeta } from './utils/rpcMeta.js';
|
|
7
|
-
import { getStoredSpanContext, buildSpanLinks
|
|
8
|
+
import { storeSpanContext, getStoredSpanContext, buildSpanLinks } from './utils/traceLinks.js';
|
|
8
9
|
|
|
9
10
|
function resolveOriginalStorage(context, thisArg) {
|
|
10
11
|
if (isObjectLike(thisArg) && "ctx" in thisArg) {
|
|
@@ -31,9 +32,11 @@ function wrapMethodWithSentry(wrapperOptions, handler, callback, noMark) {
|
|
|
31
32
|
args = extracted.args;
|
|
32
33
|
rpcMeta = extracted.rpcMeta;
|
|
33
34
|
}
|
|
35
|
+
const spanName = typeof wrapperOptions.spanName === "function" ? wrapperOptions.spanName(rpcMeta) : wrapperOptions.spanName;
|
|
34
36
|
const wrappedFunction = (scope) => {
|
|
35
37
|
const context = wrapperOptions.context;
|
|
36
|
-
const
|
|
38
|
+
const invocationState = getInvocationState();
|
|
39
|
+
const waitUntil = invocationState ? getInvocationWaitUntil(invocationState) : context ? getOriginalWaitUntil(context)?.bind(context) : void 0;
|
|
37
40
|
const storage = resolveOriginalStorage(context, thisArg);
|
|
38
41
|
let scopeClient = scope.getClient();
|
|
39
42
|
if (startNewTrace$1 || !scopeClient?.getTransport()) {
|
|
@@ -45,7 +48,7 @@ function wrapMethodWithSentry(wrapperOptions, handler, callback, noMark) {
|
|
|
45
48
|
scopeClient = client;
|
|
46
49
|
}
|
|
47
50
|
const clientToDispose = scopeClient;
|
|
48
|
-
const methodName =
|
|
51
|
+
const methodName = spanName || "unknown";
|
|
49
52
|
const teardown = async () => {
|
|
50
53
|
if (startNewTrace$1 && storage) {
|
|
51
54
|
storeSpanContext(storage, methodName);
|
|
@@ -56,17 +59,23 @@ function wrapMethodWithSentry(wrapperOptions, handler, callback, noMark) {
|
|
|
56
59
|
waitUntil?.(teardown());
|
|
57
60
|
return res;
|
|
58
61
|
};
|
|
59
|
-
const
|
|
62
|
+
const captureAndRethrow = (e) => {
|
|
60
63
|
captureException(e, {
|
|
61
64
|
mechanism: {
|
|
62
65
|
type: origin,
|
|
63
66
|
handled: false
|
|
64
67
|
}
|
|
65
68
|
});
|
|
66
|
-
waitUntil?.(teardown());
|
|
67
69
|
throw e;
|
|
68
70
|
};
|
|
69
|
-
|
|
71
|
+
const onRejected = (e) => {
|
|
72
|
+
try {
|
|
73
|
+
return captureAndRethrow(e);
|
|
74
|
+
} finally {
|
|
75
|
+
waitUntil?.(teardown());
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
if (!spanName) {
|
|
70
79
|
try {
|
|
71
80
|
if (callback) {
|
|
72
81
|
callback(...args);
|
|
@@ -101,27 +110,54 @@ function wrapMethodWithSentry(wrapperOptions, handler, callback, noMark) {
|
|
|
101
110
|
try {
|
|
102
111
|
const result = Reflect.apply(target, thisArg, args);
|
|
103
112
|
if (isThenable(result)) {
|
|
104
|
-
return result.then(
|
|
105
|
-
} else {
|
|
106
|
-
return onFulfilled(result);
|
|
113
|
+
return result.then(void 0, captureAndRethrow);
|
|
107
114
|
}
|
|
115
|
+
return result;
|
|
108
116
|
} catch (e) {
|
|
109
|
-
return
|
|
117
|
+
return captureAndRethrow(e);
|
|
110
118
|
}
|
|
111
119
|
});
|
|
112
120
|
};
|
|
121
|
+
const runWithTeardown = (run) => {
|
|
122
|
+
let out;
|
|
123
|
+
try {
|
|
124
|
+
out = run();
|
|
125
|
+
} catch (e) {
|
|
126
|
+
waitUntil?.(teardown());
|
|
127
|
+
throw e;
|
|
128
|
+
}
|
|
129
|
+
if (isThenable(out)) {
|
|
130
|
+
return out.then(
|
|
131
|
+
(res) => {
|
|
132
|
+
waitUntil?.(teardown());
|
|
133
|
+
return res;
|
|
134
|
+
},
|
|
135
|
+
(e) => {
|
|
136
|
+
waitUntil?.(teardown());
|
|
137
|
+
throw e;
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
waitUntil?.(teardown());
|
|
142
|
+
return out;
|
|
143
|
+
};
|
|
113
144
|
if (rpcMeta) {
|
|
114
|
-
return
|
|
115
|
-
|
|
116
|
-
|
|
145
|
+
return runWithTeardown(
|
|
146
|
+
() => continueTrace(
|
|
147
|
+
{ sentryTrace: rpcMeta["sentry-trace"] || "", baggage: rpcMeta.baggage || "" },
|
|
148
|
+
executeSpan
|
|
149
|
+
)
|
|
117
150
|
);
|
|
118
151
|
}
|
|
119
152
|
if (startNewTrace$1) {
|
|
120
|
-
return startNewTrace(() => executeSpan());
|
|
153
|
+
return runWithTeardown(() => startNewTrace(() => executeSpan()));
|
|
121
154
|
}
|
|
122
|
-
return executeSpan
|
|
155
|
+
return runWithTeardown(executeSpan);
|
|
123
156
|
};
|
|
124
|
-
return withInvocationIsolationScope(
|
|
157
|
+
return withInvocationIsolationScope(
|
|
158
|
+
wrappedFunction,
|
|
159
|
+
wrapperOptions.context
|
|
160
|
+
);
|
|
125
161
|
}
|
|
126
162
|
}),
|
|
127
163
|
noMark
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrapMethodWithSentry.js","sources":["../../../src/wrapMethodWithSentry.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport type { SerializedTraceData } from '@sentry/core';\nimport {\n isObjectLike,\n captureException,\n continueTrace,\n isThenable,\n type Scope,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startNewTrace as startNewTraceCore,\n startSpan,\n} from '@sentry/core';\nimport type { CloudflareOptions } from './client';\nimport type { ExecutionContextCompat } from './executionContext';\nimport { flushAndDispose, getOriginalWaitUntil } from './flush';\nimport { ensureInstrumented } from './instrument';\nimport { init } from './sdk';\nimport { withInvocationIsolationScope } from './utils/invocationScope';\nimport { extractRpcMeta } from './utils/rpcMeta';\nimport { buildSpanLinks, getStoredSpanContext, storeSpanContext } from './utils/traceLinks';\n\n/** Extended DurableObjectState with originalStorage exposed by instrumentContext */\nexport interface InstrumentedDurableObjectState extends DurableObjectState {\n originalStorage?: DurableObjectStorage;\n}\n\n/**\n * Resolves uninstrumented DO storage for the current invocation.\n * Prefer `thisArg.ctx` (the live Durable Object instance) over the context captured at\n * construction time to avoid cross-DO I/O errors in the same isolate.\n */\nfunction resolveOriginalStorage(\n context: ExecutionContext | InstrumentedDurableObjectState | undefined,\n thisArg: unknown,\n): DurableObjectStorage | undefined {\n if (isObjectLike(thisArg) && 'ctx' in thisArg) {\n const doCtx = (thisArg as { ctx: InstrumentedDurableObjectState }).ctx;\n if (doCtx?.originalStorage) {\n return doCtx.originalStorage;\n }\n }\n\n if (context && 'originalStorage' in context && context.originalStorage) {\n return context.originalStorage;\n }\n\n return undefined;\n}\n\ntype MethodWrapperOptions = {\n spanName?: string;\n spanOp?: string;\n options: CloudflareOptions;\n context: ExecutionContext | InstrumentedDurableObjectState;\n /**\n * If true, starts a fresh trace instead of inheriting from a parent trace.\n * Useful for scheduled/independent invocations like alarms.\n *\n * If true, it also stores the current span context and links to the previous invocation's span.\n * Uses Durable Object storage to persist the link. The link is set asynchronously via `span.addLinks()`\n * in a `waitUntil` to avoid blocking.\n *\n * @default false\n */\n startNewTrace?: boolean;\n /**\n * The trace origin identifying which instrumentation created the span, e.g. `auto.faas.cloudflare.durable_object`.\n * Used both as the span's `sentry.origin` attribute and as the `mechanism.type` for captured exceptions.\n */\n origin: string;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type UncheckedMethod = (...args: any[]) => any;\ntype OriginalMethod = UncheckedMethod;\n\n/**\n * Wraps a method with Sentry error tracking and optional tracing.\n * Supports starting new traces and linking to previous invocations via Durable Object storage.\n *\n * @param wrapperOptions - The options for the wrapper.\n * @param handler - The method to wrap.\n * @param callback - The callback to call.\n * @param noMark - Whether to mark the method as instrumented.\n * @returns The wrapped method.\n */\nexport function wrapMethodWithSentry<T extends OriginalMethod>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n noMark?: true,\n): T {\n return ensureInstrumented(\n handler,\n original =>\n new Proxy(original, {\n apply(target, thisArg, rawArgs: Parameters<T>) {\n const { startNewTrace, origin } = wrapperOptions;\n\n // For RPC methods, extract Sentry trace context from the trailing argument.\n // The caller side (instrumentDurableObjectStub / JSRPC proxy) appends it;\n // we strip it here so the user's method never sees it.\n let args = rawArgs;\n let rpcMeta: SerializedTraceData | undefined;\n\n if (wrapperOptions.spanOp === 'rpc') {\n const extracted = extractRpcMeta(rawArgs);\n args = extracted.args;\n rpcMeta = extracted.rpcMeta;\n }\n\n const wrappedFunction = (scope: Scope): unknown | Promise<unknown> => {\n // In certain situations, the passed context can become undefined.\n // For example, for Astro while prerendering pages at build time.\n // see: https://github.com/getsentry/sentry-javascript/issues/13217\n const context: typeof wrapperOptions.context | undefined = wrapperOptions.context;\n\n // see: https://github.com/getsentry/sentry-javascript/issues/22328\n const waitUntil = context\n ? getOriginalWaitUntil(context as ExecutionContextCompat)?.bind(context)\n : undefined;\n const storage = resolveOriginalStorage(context, thisArg);\n\n let scopeClient = scope.getClient();\n // Check if client exists AND is still usable (transport not disposed)\n // This handles the case where a previous handler disposed the client\n // but the scope still holds a reference to it (e.g., alarm handlers in Durable Objects)\n // For startNewTrace, always create a fresh client\n if (startNewTrace || !scopeClient?.getTransport()) {\n const client = init({\n ...wrapperOptions.options,\n ctx: context as unknown as ExecutionContext | undefined,\n });\n scope.setClient(client);\n scopeClient = client;\n }\n\n const clientToDispose = scopeClient;\n const methodName = wrapperOptions.spanName || 'unknown';\n\n const teardown = async (): Promise<void> => {\n if (startNewTrace && storage) {\n storeSpanContext(storage, methodName);\n }\n await flushAndDispose(clientToDispose);\n };\n\n const onFulfilled = (res: unknown) => {\n waitUntil?.(teardown());\n return res;\n };\n\n const onRejected = (e: unknown) => {\n captureException(e, {\n mechanism: {\n type: origin,\n handled: false,\n },\n });\n waitUntil?.(teardown());\n throw e;\n };\n\n if (!wrapperOptions.spanName) {\n try {\n if (callback) {\n callback(...args);\n }\n\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(onFulfilled, onRejected);\n } else {\n return onFulfilled(result);\n }\n } catch (e) {\n return onRejected(e);\n }\n }\n\n const attributes = wrapperOptions.spanOp\n ? {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: origin,\n }\n : {};\n\n const executeSpan = (): unknown => {\n return startSpan({ name: methodName, attributes }, span => {\n if (startNewTrace && storage) {\n const storedContext = getStoredSpanContext(storage, methodName);\n\n if (storedContext) {\n span.addLinks(buildSpanLinks(storedContext));\n // TODO: Remove this once EAP can store span links. We currently only set this attribute so that we\n // can obtain the previous trace information from the EAP store. Long-term, EAP will handle\n // span links and then we should remove this again. Also throwing in a TODO(v11), to remind us\n // to check this at v11 time :)\n const sampledFlag = storedContext.sampled ? '1' : '0';\n span.setAttribute(\n 'sentry.previous_trace',\n `${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}`,\n );\n }\n }\n\n try {\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(onFulfilled, onRejected);\n } else {\n return onFulfilled(result);\n }\n } catch (e) {\n return onRejected(e);\n }\n });\n };\n\n if (rpcMeta) {\n return continueTrace(\n { sentryTrace: rpcMeta['sentry-trace'] || '', baggage: rpcMeta.baggage || '' },\n executeSpan,\n );\n }\n\n if (startNewTrace) {\n return startNewTraceCore(() => executeSpan());\n }\n\n return executeSpan();\n };\n\n return withInvocationIsolationScope(wrappedFunction);\n },\n }),\n noMark,\n );\n}\n"],"names":["startNewTrace","startNewTraceCore"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wrapMethodWithSentry.js","sources":["../../../src/wrapMethodWithSentry.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport type { SerializedTraceData } from '@sentry/core';\nimport {\n isObjectLike,\n captureException,\n continueTrace,\n isThenable,\n type Scope,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startNewTrace as startNewTraceCore,\n startSpan,\n} from '@sentry/core';\nimport type { CloudflareOptions } from './client';\nimport type { ExecutionContextCompat } from './executionContext';\nimport { flushAndDispose, getOriginalWaitUntil } from './flush';\nimport { ensureInstrumented } from './instrument';\nimport { init } from './sdk';\nimport { getInvocationState, getInvocationWaitUntil } from './utils/invocationContext';\nimport { withInvocationIsolationScope } from './utils/invocationScope';\nimport { extractRpcMeta } from './utils/rpcMeta';\nimport { buildSpanLinks, getStoredSpanContext, storeSpanContext } from './utils/traceLinks';\n\n/** Extended DurableObjectState with originalStorage exposed by instrumentContext */\nexport interface InstrumentedDurableObjectState extends DurableObjectState {\n originalStorage?: DurableObjectStorage;\n}\n\n/**\n * Resolves uninstrumented DO storage for the current invocation.\n * Prefer `thisArg.ctx` (the live Durable Object instance) over the context captured at\n * construction time to avoid cross-DO I/O errors in the same isolate.\n */\nfunction resolveOriginalStorage(\n context: ExecutionContext | InstrumentedDurableObjectState | undefined,\n thisArg: unknown,\n): DurableObjectStorage | undefined {\n if (isObjectLike(thisArg) && 'ctx' in thisArg) {\n const doCtx = (thisArg as { ctx: InstrumentedDurableObjectState }).ctx;\n if (doCtx?.originalStorage) {\n return doCtx.originalStorage;\n }\n }\n\n if (context && 'originalStorage' in context && context.originalStorage) {\n return context.originalStorage;\n }\n\n return undefined;\n}\n\ntype MethodWrapperOptions = {\n /**\n * The span name, or a resolver called with the RPC metadata of the current call.\n * Returning `undefined` skips the span and only captures errors.\n */\n spanName?: string | ((rpcMeta: SerializedTraceData | undefined) => string | undefined);\n spanOp?: string;\n options: CloudflareOptions;\n context: ExecutionContext | InstrumentedDurableObjectState;\n /**\n * If true, starts a fresh trace instead of inheriting from a parent trace.\n * Useful for scheduled/independent invocations like alarms.\n *\n * If true, it also stores the current span context and links to the previous invocation's span.\n * Uses Durable Object storage to persist the link. The link is set asynchronously via `span.addLinks()`\n * in a `waitUntil` to avoid blocking.\n *\n * @default false\n */\n startNewTrace?: boolean;\n /**\n * The trace origin identifying which instrumentation created the span, e.g. `auto.faas.cloudflare.durable_object`.\n * Used both as the span's `sentry.origin` attribute and as the `mechanism.type` for captured exceptions.\n */\n origin: string;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type UncheckedMethod = (...args: any[]) => any;\ntype OriginalMethod = UncheckedMethod;\n\n/**\n * Wraps a method with Sentry error tracking and optional tracing.\n * Supports starting new traces and linking to previous invocations via Durable Object storage.\n *\n * @param wrapperOptions - The options for the wrapper.\n * @param handler - The method to wrap.\n * @param callback - The callback to call.\n * @param noMark - Whether to mark the method as instrumented.\n * @returns The wrapped method.\n */\nexport function wrapMethodWithSentry<T extends OriginalMethod>(\n wrapperOptions: MethodWrapperOptions,\n handler: T,\n callback?: (...args: Parameters<T>) => void,\n noMark?: true,\n): T {\n return ensureInstrumented(\n handler,\n original =>\n new Proxy(original, {\n apply(target, thisArg, rawArgs: Parameters<T>) {\n const { startNewTrace, origin } = wrapperOptions;\n\n // For RPC methods, extract Sentry trace context from the trailing argument.\n // The caller side (instrumentDurableObjectStub / JSRPC proxy) appends it;\n // we strip it here so the user's method never sees it.\n let args = rawArgs;\n let rpcMeta: SerializedTraceData | undefined;\n\n if (wrapperOptions.spanOp === 'rpc') {\n const extracted = extractRpcMeta(rawArgs);\n args = extracted.args;\n rpcMeta = extracted.rpcMeta;\n }\n\n const spanName =\n typeof wrapperOptions.spanName === 'function' ? wrapperOptions.spanName(rpcMeta) : wrapperOptions.spanName;\n\n const wrappedFunction = (scope: Scope): unknown | Promise<unknown> => {\n // In certain situations, the passed context can become undefined.\n // For example, for Astro while prerendering pages at build time.\n // see: https://github.com/getsentry/sentry-javascript/issues/13217\n const context: typeof wrapperOptions.context | undefined = wrapperOptions.context;\n\n // see: https://github.com/getsentry/sentry-javascript/issues/22328\n // Resolved once per invocation and cached on its state: reading `ctx.waitUntil`\n // on a native context is a runtime getter call.\n const invocationState = getInvocationState();\n const waitUntil = invocationState\n ? getInvocationWaitUntil(invocationState)\n : context\n ? getOriginalWaitUntil(context as ExecutionContextCompat)?.bind(context)\n : undefined;\n const storage = resolveOriginalStorage(context, thisArg);\n\n let scopeClient = scope.getClient();\n // Re-init when the scope has no usable client (a previous handler disposed it, e.g.\n // DO alarm handlers) or for `startNewTrace`, so the client points at this\n // invocation's context. With `cacheClient: true` `init()` returns the isolate's\n // cached client and only creates (and caches) a fresh one when nothing is cached yet;\n // `cacheClient: false` creates one per invocation.\n if (startNewTrace || !scopeClient?.getTransport()) {\n const client = init({\n ...wrapperOptions.options,\n ctx: context as unknown as ExecutionContext | undefined,\n });\n scope.setClient(client);\n scopeClient = client;\n }\n\n const clientToDispose = scopeClient;\n const methodName = spanName || 'unknown';\n\n const teardown = async (): Promise<void> => {\n if (startNewTrace && storage) {\n storeSpanContext(storage, methodName);\n }\n await flushAndDispose(clientToDispose);\n };\n\n const onFulfilled = (res: unknown) => {\n waitUntil?.(teardown());\n return res;\n };\n\n const captureAndRethrow = (e: unknown): never => {\n captureException(e, {\n mechanism: {\n type: origin,\n handled: false,\n },\n });\n throw e;\n };\n\n const onRejected = (e: unknown) => {\n try {\n return captureAndRethrow(e);\n } finally {\n waitUntil?.(teardown());\n }\n };\n\n if (!spanName) {\n try {\n if (callback) {\n callback(...args);\n }\n\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(onFulfilled, onRejected);\n } else {\n return onFulfilled(result);\n }\n } catch (e) {\n return onRejected(e);\n }\n }\n\n const attributes = wrapperOptions.spanOp\n ? {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: origin,\n }\n : {};\n\n const executeSpan = (): unknown => {\n return startSpan({ name: methodName, attributes }, span => {\n if (startNewTrace && storage) {\n const storedContext = getStoredSpanContext(storage, methodName);\n\n if (storedContext) {\n span.addLinks(buildSpanLinks(storedContext));\n // TODO: Remove this once EAP can store span links. We currently only set this attribute so that we\n // can obtain the previous trace information from the EAP store. Long-term, EAP will handle\n // span links and then we should remove this again. Also throwing in a TODO(v11), to remind us\n // to check this at v11 time :)\n const sampledFlag = storedContext.sampled ? '1' : '0';\n span.setAttribute(\n 'sentry.previous_trace',\n `${storedContext.traceId}-${storedContext.spanId}-${sampledFlag}`,\n );\n }\n }\n\n try {\n const result = Reflect.apply(target, thisArg, args);\n\n if (isThenable(result)) {\n return result.then(undefined, captureAndRethrow);\n }\n return result;\n } catch (e) {\n return captureAndRethrow(e);\n }\n });\n };\n\n // The boundary flush (teardown) must run after the method span has ended, so the\n // span is in the buffer when that flush drains it. Running it inside the span\n // callback (before `startSpan` ends the span) would leave the span for the eager\n // path and cost a second flush per invocation.\n const runWithTeardown = (run: () => unknown): unknown => {\n let out: unknown;\n try {\n out = run();\n } catch (e) {\n // Synchronous throw: `startSpan` already ended the span and rethrew.\n waitUntil?.(teardown());\n throw e;\n }\n if (isThenable(out)) {\n return out.then(\n res => {\n waitUntil?.(teardown());\n return res;\n },\n e => {\n waitUntil?.(teardown());\n throw e;\n },\n );\n }\n waitUntil?.(teardown());\n return out;\n };\n\n if (rpcMeta) {\n return runWithTeardown(() =>\n continueTrace(\n { sentryTrace: rpcMeta['sentry-trace'] || '', baggage: rpcMeta.baggage || '' },\n executeSpan,\n ),\n );\n }\n\n if (startNewTrace) {\n return runWithTeardown(() => startNewTraceCore(() => executeSpan()));\n }\n\n return runWithTeardown(executeSpan);\n };\n\n return withInvocationIsolationScope(\n wrappedFunction,\n wrapperOptions.context as ExecutionContextCompat | undefined,\n );\n },\n }),\n noMark,\n );\n}\n"],"names":["startNewTrace","startNewTraceCore"],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP, NETWORK_PROTOCOL_NAME, NETWORK_PROTOCOL_VERSION } from '@sentry/conventions/attributes';
|
|
2
|
+
import { HTTP_SERVER } from '@sentry/conventions/op';
|
|
3
|
+
import { parseStringToURLObject, getHttpSpanDetailsFromUrlObject, hasSpanStreamingEnabled, HTTP_SPAN_NAME_FALLBACK, httpHeadersToSpanAttributes, winterCGHeadersToDict, captureException, continueTrace, startSpanManual, setHttpStatus } from '@sentry/core';
|
|
4
|
+
import { captureIncomingRequestBody } from './integrations/httpServer.js';
|
|
5
|
+
import { getOriginalWaitUntil, flushAndDispose } from './flush.js';
|
|
6
|
+
import { addCloudResourceContext, addRequest, addCultureContext } from './scope-utils.js';
|
|
7
|
+
import { getInvocationState, getInvocationWaitUntil } from './utils/invocationContext.js';
|
|
8
|
+
import { withInvocationIsolationScope } from './utils/invocationScope.js';
|
|
9
|
+
import { classifyResponseStreaming } from './utils/streaming.js';
|
|
10
|
+
|
|
11
|
+
function getRequestErrorMechanismType(context) {
|
|
12
|
+
return context && "storage" in context ? "auto.faas.cloudflare.durable_object" : "auto.http.cloudflare";
|
|
13
|
+
}
|
|
14
|
+
function wrapRequestHandlerWithInit(wrapperOptions, handler, initSdk) {
|
|
15
|
+
return withInvocationIsolationScope(async (isolationScope) => {
|
|
16
|
+
const { options, request, captureErrors = true } = wrapperOptions;
|
|
17
|
+
const context = wrapperOptions.context;
|
|
18
|
+
const invocationState = getInvocationState();
|
|
19
|
+
const waitUntil = invocationState ? getInvocationWaitUntil(invocationState) : context ? getOriginalWaitUntil(context).bind(context) : void 0;
|
|
20
|
+
const errorMechanismType = getRequestErrorMechanismType(context);
|
|
21
|
+
const client = initSdk({ ...options, ctx: context });
|
|
22
|
+
isolationScope.setClient(client);
|
|
23
|
+
const urlObject = parseStringToURLObject(request.url);
|
|
24
|
+
const [rawName, attributes] = getHttpSpanDetailsFromUrlObject(
|
|
25
|
+
urlObject,
|
|
26
|
+
"server",
|
|
27
|
+
"auto.http.cloudflare",
|
|
28
|
+
request,
|
|
29
|
+
void 0,
|
|
30
|
+
client
|
|
31
|
+
);
|
|
32
|
+
const name = attributes[SENTRY_SEGMENT_NAME_SOURCE] === "route" || !client || !hasSpanStreamingEnabled(client) ? rawName : request.method?.toUpperCase() || HTTP_SPAN_NAME_FALLBACK;
|
|
33
|
+
const contentLength = request.headers.get("content-length");
|
|
34
|
+
if (contentLength) {
|
|
35
|
+
attributes["http.request.body.size"] = parseInt(contentLength, 10);
|
|
36
|
+
}
|
|
37
|
+
const userAgentHeader = request.headers.get("user-agent");
|
|
38
|
+
if (userAgentHeader) {
|
|
39
|
+
attributes["user_agent.original"] = userAgentHeader;
|
|
40
|
+
}
|
|
41
|
+
if (client) {
|
|
42
|
+
Object.assign(
|
|
43
|
+
attributes,
|
|
44
|
+
httpHeadersToSpanAttributes(winterCGHeadersToDict(request.headers), client.getDataCollectionOptions())
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
attributes[SENTRY_OP] = HTTP_SERVER;
|
|
48
|
+
addCloudResourceContext(isolationScope);
|
|
49
|
+
addRequest(isolationScope, request);
|
|
50
|
+
if (request.cf) {
|
|
51
|
+
addCultureContext(isolationScope, request.cf);
|
|
52
|
+
if (typeof request.cf.httpProtocol === "string") {
|
|
53
|
+
const [protocolName, protocolVersion] = request.cf.httpProtocol.toLowerCase().split("/");
|
|
54
|
+
attributes[NETWORK_PROTOCOL_NAME] = protocolName;
|
|
55
|
+
attributes[NETWORK_PROTOCOL_VERSION] = protocolVersion;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (request.method === "OPTIONS" || request.method === "HEAD") {
|
|
59
|
+
try {
|
|
60
|
+
return await handler();
|
|
61
|
+
} catch (e) {
|
|
62
|
+
if (captureErrors) {
|
|
63
|
+
captureException(e, { mechanism: { handled: false, type: errorMechanismType } });
|
|
64
|
+
}
|
|
65
|
+
throw e;
|
|
66
|
+
} finally {
|
|
67
|
+
waitUntil?.(flushAndDispose(client));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (client) {
|
|
71
|
+
await captureIncomingRequestBody(client, request);
|
|
72
|
+
}
|
|
73
|
+
return continueTrace(
|
|
74
|
+
{ sentryTrace: request.headers.get("sentry-trace") || "", baggage: request.headers.get("baggage") },
|
|
75
|
+
() => {
|
|
76
|
+
return startSpanManual({ name, attributes }, async (span) => {
|
|
77
|
+
let res;
|
|
78
|
+
try {
|
|
79
|
+
res = await handler();
|
|
80
|
+
setHttpStatus(span, res.status);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
span.end();
|
|
83
|
+
if (captureErrors) {
|
|
84
|
+
captureException(e, { mechanism: { handled: false, type: errorMechanismType } });
|
|
85
|
+
}
|
|
86
|
+
waitUntil?.(flushAndDispose(client));
|
|
87
|
+
throw e;
|
|
88
|
+
}
|
|
89
|
+
const classification = classifyResponseStreaming(res);
|
|
90
|
+
if (classification.isStreaming && res.body) {
|
|
91
|
+
try {
|
|
92
|
+
let ended = false;
|
|
93
|
+
const endSpanOnce = () => {
|
|
94
|
+
if (ended) return;
|
|
95
|
+
ended = true;
|
|
96
|
+
span.end();
|
|
97
|
+
waitUntil?.(flushAndDispose(client));
|
|
98
|
+
};
|
|
99
|
+
const transform = new TransformStream({
|
|
100
|
+
flush() {
|
|
101
|
+
endSpanOnce();
|
|
102
|
+
},
|
|
103
|
+
cancel() {
|
|
104
|
+
endSpanOnce();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return new Response(res.body.pipeThrough(transform), {
|
|
108
|
+
status: res.status,
|
|
109
|
+
statusText: res.statusText,
|
|
110
|
+
headers: res.headers
|
|
111
|
+
});
|
|
112
|
+
} catch {
|
|
113
|
+
span.end();
|
|
114
|
+
waitUntil?.(flushAndDispose(client));
|
|
115
|
+
return res;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
span.end();
|
|
119
|
+
if (res.status === 101) {
|
|
120
|
+
waitUntil?.(client?.flush(2e3));
|
|
121
|
+
} else {
|
|
122
|
+
waitUntil?.(flushAndDispose(client));
|
|
123
|
+
}
|
|
124
|
+
return res;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
}, wrapperOptions.context);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export { wrapRequestHandlerWithInit };
|
|
132
|
+
//# sourceMappingURL=wrapRequestHandlerWithInit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapRequestHandlerWithInit.js","sources":["../../../src/wrapRequestHandlerWithInit.ts"],"sourcesContent":["import type { CfProperties, IncomingRequestCfProperties } from '@cloudflare/workers-types';\nimport {\n NETWORK_PROTOCOL_NAME,\n NETWORK_PROTOCOL_VERSION,\n SENTRY_OP,\n SENTRY_SEGMENT_NAME_SOURCE,\n} from '@sentry/conventions/attributes';\nimport { HTTP_SERVER } from '@sentry/conventions/op';\nimport {\n captureException,\n continueTrace,\n getHttpSpanDetailsFromUrlObject,\n hasSpanStreamingEnabled,\n httpHeadersToSpanAttributes,\n HTTP_SPAN_NAME_FALLBACK,\n parseStringToURLObject,\n setHttpStatus,\n startSpanManual,\n winterCGHeadersToDict,\n} from '@sentry/core';\nimport { captureIncomingRequestBody } from './integrations/httpServer';\nimport type { CloudflareClient, CloudflareOptions } from './client';\nimport type { ExecutionContextCompat } from './executionContext';\nimport { flushAndDispose, getOriginalWaitUntil } from './flush';\nimport { addCloudResourceContext, addCultureContext, addRequest } from './scope-utils';\nimport { getInvocationState, getInvocationWaitUntil } from './utils/invocationContext';\nimport { withInvocationIsolationScope } from './utils/invocationScope';\nimport { classifyResponseStreaming } from './utils/streaming';\n\nfunction getRequestErrorMechanismType(context: ExecutionContextCompat | undefined): string {\n // Durable Object fetch handlers use DO state as context (see instrumentDurableObjectWithSentry)\n return context && 'storage' in context ? 'auto.faas.cloudflare.durable_object' : 'auto.http.cloudflare';\n}\n\nexport interface RequestHandlerWrapperOptions {\n options: CloudflareOptions;\n request: Request<unknown, IncomingRequestCfProperties<unknown> | CfProperties<unknown>>;\n context: ExecutionContextCompat | undefined;\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\ntype InitSdk = (options: CloudflareOptions) => CloudflareClient | undefined;\n\n/**\n * Same as {@link wrapRequestHandler}, but with the SDK initialization injected.\n *\n * Wrappers that are only reachable from the main entry point — where `nodejs_compat` is a\n * requirement anyway — pass `init` from `sdk.ts` to get the full default integrations.\n *\n * @internal\n */\nexport function wrapRequestHandlerWithInit(\n wrapperOptions: RequestHandlerWrapperOptions,\n handler: (...args: unknown[]) => Response | Promise<Response>,\n initSdk: InitSdk,\n): Promise<Response> {\n return withInvocationIsolationScope(async isolationScope => {\n const { options, request, captureErrors = true } = wrapperOptions;\n const context = wrapperOptions.context;\n\n // The un-instrumented waitUntil, so flushAndDispose cannot deadlock on the flush\n // lock's own wrapper. Resolved once per invocation and cached on its state; reading\n // `ctx.waitUntil` on a native context is a runtime getter call.\n const invocationState = getInvocationState();\n const waitUntil = invocationState\n ? getInvocationWaitUntil(invocationState)\n : context\n ? getOriginalWaitUntil(context).bind(context)\n : undefined;\n const errorMechanismType = getRequestErrorMechanismType(context);\n\n const client = initSdk({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n const urlObject = parseStringToURLObject(request.url);\n const [rawName, attributes] = getHttpSpanDetailsFromUrlObject(\n urlObject,\n 'server',\n 'auto.http.cloudflare',\n request,\n undefined,\n client,\n );\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL.\n // A `route` source means the name already is (e.g. the `/` path), so it is kept as-is.\n const name =\n attributes[SENTRY_SEGMENT_NAME_SOURCE] === 'route' || !client || !hasSpanStreamingEnabled(client)\n ? rawName\n : request.method?.toUpperCase() || HTTP_SPAN_NAME_FALLBACK;\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 if (client) {\n Object.assign(\n attributes,\n httpHeadersToSpanAttributes(winterCGHeadersToDict(request.headers), client.getDataCollectionOptions()),\n );\n }\n\n attributes[SENTRY_OP] = HTTP_SERVER;\n\n addCloudResourceContext(isolationScope);\n addRequest(isolationScope, request);\n if (request.cf) {\n addCultureContext(isolationScope, request.cf);\n\n if (typeof request.cf.httpProtocol === 'string') {\n const [protocolName, protocolVersion] = request.cf.httpProtocol.toLowerCase().split('/');\n attributes[NETWORK_PROTOCOL_NAME] = protocolName;\n attributes[NETWORK_PROTOCOL_VERSION] = protocolVersion;\n }\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: errorMechanismType } });\n }\n throw e;\n } finally {\n waitUntil?.(flushAndDispose(client));\n }\n }\n\n if (client) {\n await captureIncomingRequestBody(client, request);\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: errorMechanismType } });\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 try {\n let ended = false;\n\n const endSpanOnce = (): void => {\n if (ended) return;\n\n ended = true;\n span.end();\n waitUntil?.(flushAndDispose(client));\n };\n\n const transform = new TransformStream({\n flush() {\n // Source stream completed normally.\n endSpanOnce();\n },\n cancel() {\n // Client disconnected (or downstream cancelled). The `cancel`\n // is being called while the response is still considered\n // active, so this is a safe place to end the span.\n endSpanOnce();\n },\n });\n\n return new Response(res.body.pipeThrough(transform), {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n } catch {\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 }, wrapperOptions.context);\n}\n"],"names":[],"mappings":"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"}
|
package/build/types/baseSdk.d.ts
CHANGED
|
@@ -17,6 +17,14 @@ export declare function getBaseDefaultIntegrations(options: CloudflareOptions):
|
|
|
17
17
|
* Node.js-only code. `request.ts` — which backs both `wrapRequestHandler` and the
|
|
18
18
|
* `@sentry/cloudflare/request` entry point, and therefore has to work on runtimes without the
|
|
19
19
|
* `nodejs_compat` compatibility flag — creates its client from here instead of from `sdk.ts`.
|
|
20
|
+
*
|
|
21
|
+
* The client is cached and reused across invocations within the same isolate,
|
|
22
|
+
* unless `cacheClient: false` is passed. This avoids the
|
|
23
|
+
* per-invocation cost of constructing a new client, and it is what makes
|
|
24
|
+
* Durable Object telemetry reliable: a per-invocation client is disposed at
|
|
25
|
+
* the end of the handler, and in a Durable Object there is no `waitUntil`
|
|
26
|
+
* boundary that reliably extends execution, so spans/events that end after
|
|
27
|
+
* disposal would otherwise be lost.
|
|
20
28
|
*/
|
|
21
29
|
export declare function initWithDefaultIntegrations(options: CloudflareOptions, getDefaultIntegrationsImpl: (options: CloudflareOptions) => Integration[]): CloudflareClient | undefined;
|
|
22
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseSdk.d.ts","sourceRoot":"","sources":["../../src/baseSdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"baseSdk.d.ts","sourceRoot":"","sources":["../../src/baseSdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAehD,OAAO,KAAK,EAA2B,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AA0B5C;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,iBAAiB,GAAG,WAAW,EAAE,CAqBpF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,iBAAiB,EAC1B,0BAA0B,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,WAAW,EAAE,GACxE,gBAAgB,GAAG,SAAS,CAiE9B;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,SAAS,CAEpF"}
|
package/build/types/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ClientOptions, Options } from '@sentry/core';
|
|
2
|
-
import { ServerRuntimeClient } from '@sentry/core';
|
|
1
|
+
import type { ClientOptions, Options, TracePropagationTargets } from '@sentry/core';
|
|
2
|
+
import { ServerRuntimeClient } from '@sentry/core/server';
|
|
3
3
|
import type { ExecutionContextCompat } from './executionContext';
|
|
4
4
|
import type { makeFlushLock } from './flush';
|
|
5
5
|
import type { CloudflareTransportOptions } from './transport';
|
|
@@ -16,6 +16,13 @@ export declare class CloudflareClient extends ServerRuntimeClient {
|
|
|
16
16
|
private _resolveSpanCompletion;
|
|
17
17
|
private _unsubscribeSpanStart;
|
|
18
18
|
private _unsubscribeSpanEnd;
|
|
19
|
+
private _inBoundaryFlush;
|
|
20
|
+
/**
|
|
21
|
+
* Whether this client is a cached, cross-invocation client (`cacheClient`).
|
|
22
|
+
* Cached clients are never disposed at an invocation boundary, so their spans/events
|
|
23
|
+
* are delivered eagerly instead of waiting for a per-invocation flush.
|
|
24
|
+
*/
|
|
25
|
+
readonly isCachedClient: boolean;
|
|
19
26
|
/**
|
|
20
27
|
* Creates a new Cloudflare SDK instance.
|
|
21
28
|
* @param options Configuration options for this SDK.
|
|
@@ -47,6 +54,39 @@ export declare class CloudflareClient extends ServerRuntimeClient {
|
|
|
47
54
|
* Resets the span completion promise and resolve function.
|
|
48
55
|
*/
|
|
49
56
|
private _resetSpanCompletionPromise;
|
|
57
|
+
/**
|
|
58
|
+
* Drains the transport after an envelope has been accepted past the invocation's
|
|
59
|
+
* flush point. The transport queues request producers until `flush()`; before the
|
|
60
|
+
* flush point the boundary `flush()` drains everything, but envelopes created after
|
|
61
|
+
* it (post-response `waitUntil` work, detached continuations) have no later flush to
|
|
62
|
+
* ride. The drain is registered with the invocation's `waitUntil` to keep the fetch
|
|
63
|
+
* alive; outside any instrumented invocation it always runs.
|
|
64
|
+
*/
|
|
65
|
+
private _setupEagerEnvelopeDelivery;
|
|
66
|
+
/**
|
|
67
|
+
* Turns spans, logs and metrics captured past the invocation's flush point into
|
|
68
|
+
* envelopes. Before the flush point the boundary `flush()` drains their buffers; after
|
|
69
|
+
* it (or outside any instrumented invocation) nothing else would: the log/metric idle
|
|
70
|
+
* timer is disabled for this runtime (`_flushInterval: 0`) and the span buffer's own 5s
|
|
71
|
+
* timer fires outside any invocation, where the runtime suspends the send. Each capture
|
|
72
|
+
* drains only its own bucket (the ended span's trace, the log buffer, the metric
|
|
73
|
+
* buffer), so a fan-out of concurrent traces stays one envelope per trace. RPC method
|
|
74
|
+
* spans never reach this path: `wrapMethodWithSentry` runs the boundary flush after the
|
|
75
|
+
* method span has ended, so only work past that (e.g. detached continuations) lands here.
|
|
76
|
+
*/
|
|
77
|
+
private _setupEagerBufferDelivery;
|
|
78
|
+
/**
|
|
79
|
+
* Runs `drain` unless the owning invocation has not reached its flush point yet
|
|
80
|
+
* (before it the boundary `flush()` delivers the buffers).
|
|
81
|
+
*/
|
|
82
|
+
private _eagerDrain;
|
|
83
|
+
/**
|
|
84
|
+
* Attaches a promise to the `waitUntil` of the invocation that owns the current
|
|
85
|
+
* async context, so the runtime keeps the send alive after the response is returned.
|
|
86
|
+
* Outside any instrumented invocation (or where the context has no `waitUntil`,
|
|
87
|
+
* e.g. Astro prerendering) the send is fire-and-forget.
|
|
88
|
+
*/
|
|
89
|
+
private _registerWithInvocationWaitUntil;
|
|
50
90
|
}
|
|
51
91
|
interface BaseCloudflareOptions {
|
|
52
92
|
/**
|
|
@@ -68,35 +108,40 @@ interface BaseCloudflareOptions {
|
|
|
68
108
|
*/
|
|
69
109
|
enableOpenTelemetrySetup?: boolean;
|
|
70
110
|
/**
|
|
71
|
-
*
|
|
111
|
+
* The bindings on `env` that outgoing RPC calls propagate trace context to.
|
|
72
112
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* - Service binding `fetch()` calls (via HTTP headers)
|
|
76
|
-
* - RPC method calls to Durable Objects and WorkerEntrypoints (via trailing argument)
|
|
113
|
+
* Strings match a binding name exactly, regular expressions match by pattern. An empty array
|
|
114
|
+
* (the default) propagates to nothing.
|
|
77
115
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
116
|
+
* RPC has no headers to carry trace context, so the SDK appends it as a trailing argument to
|
|
117
|
+
* every RPC method call on a matching binding. Only a Sentry-instrumented receiver strips that
|
|
118
|
+
* argument again. Anywhere else it arrives as a real argument and changes what the method was
|
|
119
|
+
* called with, so list only the bindings whose receiver you know runs Sentry.
|
|
82
120
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
121
|
+
* Propagation over `stub.fetch()` and service binding `fetch()` uses HTTP headers and is not
|
|
122
|
+
* affected by this option.
|
|
85
123
|
*
|
|
86
|
-
*
|
|
124
|
+
* Strings match a binding name exactly, regular expressions match by pattern. Both match
|
|
125
|
+
* case-insensitively.
|
|
126
|
+
*
|
|
127
|
+
* When you build with the Sentry Cloudflare Vite plugin, bindings that resolve to *this* worker
|
|
128
|
+
* (its own Durable Objects, its self service bindings) are added for you, because the plugin
|
|
129
|
+
* instruments those receivers itself. Whatever you list here is added on top of them.
|
|
130
|
+
*
|
|
131
|
+
* @default []
|
|
87
132
|
* @example
|
|
88
133
|
* ```ts
|
|
89
|
-
* //
|
|
134
|
+
* // Propagate to `env.ORDERS` and every `env.SVC_*` binding
|
|
90
135
|
* export default Sentry.withSentry(
|
|
91
|
-
*
|
|
136
|
+
* env => ({
|
|
92
137
|
* dsn: env.SENTRY_DSN,
|
|
93
|
-
*
|
|
138
|
+
* rpcTracePropagationBindings: ['ORDERS', /^SVC_/],
|
|
94
139
|
* }),
|
|
95
140
|
* handler,
|
|
96
141
|
* );
|
|
97
142
|
* ```
|
|
98
143
|
*/
|
|
99
|
-
|
|
144
|
+
rpcTracePropagationBindings?: TracePropagationTargets;
|
|
100
145
|
/**
|
|
101
146
|
* Table names that should stay instrumented even though they match the reserved `cf_` prefix used
|
|
102
147
|
* by Durable Object frameworks (`agents`, `partyserver`, ...) for their internal SQLite tables.
|
|
@@ -144,6 +189,12 @@ interface BaseCloudflareOptions {
|
|
|
144
189
|
* ```
|
|
145
190
|
*/
|
|
146
191
|
durableObjectStorageSpanAllowlist?: Array<string | RegExp>;
|
|
192
|
+
/**
|
|
193
|
+
* Sets an optional server name (device name).
|
|
194
|
+
*
|
|
195
|
+
* This is useful for identifying which server or instance is sending events.
|
|
196
|
+
*/
|
|
197
|
+
serverName?: string;
|
|
147
198
|
/**
|
|
148
199
|
* If you use Spotlight by Sentry during development, use
|
|
149
200
|
* this option to forward captured Sentry events to Spotlight.
|
|
@@ -155,6 +206,28 @@ interface BaseCloudflareOptions {
|
|
|
155
206
|
* IMPORTANT: Only set this option to `true` while developing, not in production!
|
|
156
207
|
*/
|
|
157
208
|
spotlight?: boolean | string;
|
|
209
|
+
/**
|
|
210
|
+
* Cache the client and reuse it across invocations within the same isolate.
|
|
211
|
+
*
|
|
212
|
+
* The SDK creates one client per isolate and reuses it for all requests/DO
|
|
213
|
+
* handlers in that isolate. This avoids the per-invocation cost of
|
|
214
|
+
* constructing a new client.
|
|
215
|
+
*
|
|
216
|
+
* Since a cached client outlives any single invocation, data captured after an
|
|
217
|
+
* invocation's flush point (post-response `waitUntil` work, detached background
|
|
218
|
+
* work) is delivered eagerly instead of waiting for a flush that never comes.
|
|
219
|
+
*
|
|
220
|
+
* The first `init()` in an isolate decides the cached client's options; later
|
|
221
|
+
* `init()` calls with different options (e.g. another DSN) reuse the cached client
|
|
222
|
+
* unchanged (a debug warning is logged for a DSN change). Use `cacheClient: false`
|
|
223
|
+
* when options must differ per invocation.
|
|
224
|
+
*
|
|
225
|
+
* When disabled, a new client is created per invocation and disposed after the
|
|
226
|
+
* handler completes.
|
|
227
|
+
*
|
|
228
|
+
* @default true
|
|
229
|
+
*/
|
|
230
|
+
cacheClient?: boolean;
|
|
158
231
|
}
|
|
159
232
|
/**
|
|
160
233
|
* Configuration options for the Sentry Cloudflare SDK
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAUpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAG9D;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,mBAAmB;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,sBAAsB,CAA8B;IAC5D,OAAO,CAAC,sBAAsB,CAA6B;IAE3D,OAAO,CAAC,qBAAqB,CAA6B;IAC1D,OAAO,CAAC,mBAAmB,CAA6B;IAIxD,OAAO,CAAC,gBAAgB,CAAS;IAEjC;;;;OAIG;IACH,SAAgB,cAAc,EAAE,OAAO,CAAC;IAExC;;;OAGG;IACH,YAAmB,OAAO,EAAE,uBAAuB,EA0DlD;IAED;;;;;;;;OAQG;IACU,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoCrD;IAED;;;;;;;;OAQG;IACa,OAAO,IAAI,IAAI,CAgB9B;IAED,kBAAkB;IAClB,UAAmB,kBAAkB,IAAI,IAAI,CA0B5C;IAED;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAMnC;;;;;;;OAOG;IACH,OAAO,CAAC,2BAA2B;IAanC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,yBAAyB;IAajC;;;OAGG;IACH,OAAO,CAAC,WAAW;IAUnB;;;;;OAKG;IACH,OAAO,CAAC,gCAAgC;CAkBzC;AAED,UAAU,qBAAqB;IAC7B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;;;;;OAUG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,2BAA2B,CAAC,EAAE,uBAAuB,CAAC;IAEtD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,6BAA6B,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAEvD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,iCAAiC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAE3D;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAE7B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,0BAA0B,CAAC,EAAE,qBAAqB;IACnG,GAAG,CAAC,EAAE,sBAAsB,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAwB,SAAQ,aAAa,CAAC,0BAA0B,CAAC,EAAE,qBAAqB;IAC/G,SAAS,CAAC,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;CAC9C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CloudflareClient } from './client';
|
|
2
|
+
/** Returns the one cached Cloudflare client for this isolate. */
|
|
3
|
+
export declare function getCachedClient(): CloudflareClient | undefined;
|
|
4
|
+
/** Stores the one Cloudflare client reused by every invocation in this isolate. */
|
|
5
|
+
export declare function cacheClient(client: CloudflareClient): void;
|
|
6
|
+
/** @hidden Only for testing - clears the isolate's cached Cloudflare client. */
|
|
7
|
+
export declare function _clearGlobalClientCache(): void;
|
|
8
|
+
//# sourceMappingURL=clientCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientCache.d.ts","sourceRoot":"","sources":["../../src/clientCache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAQjD,iEAAiE;AACjE,wBAAgB,eAAe,IAAI,gBAAgB,GAAG,SAAS,CAE9D;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAE1D;AAED,gFAAgF;AAChF,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CloudflareOptions } from './client';
|
|
2
|
-
import type { DefaultEnv } from './types';
|
|
2
|
+
import type { DefaultEnv, StrictCloudflareOptions } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Define the Sentry options for a Cloudflare Worker in a dedicated module.
|
|
5
5
|
*
|
|
@@ -34,5 +34,6 @@ import type { DefaultEnv } from './types';
|
|
|
34
34
|
* export default defineCloudflareOptions({ tracesSampleRate: 1.0 });
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
|
-
export declare function defineCloudflareOptions<Env = DefaultEnv>(
|
|
37
|
+
export declare function defineCloudflareOptions<Env = DefaultEnv, O = unknown>(callback: (env: Env) => StrictCloudflareOptions<O> | undefined): (env: Env) => CloudflareOptions | undefined;
|
|
38
|
+
export declare function defineCloudflareOptions<Env = DefaultEnv>(options: CloudflareOptions): (env: Env) => CloudflareOptions | undefined;
|
|
38
39
|
//# sourceMappingURL=defineCloudflareOptions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defineCloudflareOptions.d.ts","sourceRoot":"","sources":["../../src/defineCloudflareOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"defineCloudflareOptions.d.ts","sourceRoot":"","sources":["../../src/defineCloudflareOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAKH,wBAAgB,uBAAuB,CAAC,GAAG,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,EACnE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,uBAAuB,CAAC,CAAC,CAAC,GAAG,SAAS,GAC7D,CAAC,GAAG,EAAE,GAAG,KAAK,iBAAiB,GAAG,SAAS,CAAC;AAC/C,wBAAgB,uBAAuB,CAAC,GAAG,GAAG,UAAU,EACtD,OAAO,EAAE,iBAAiB,GACzB,CAAC,GAAG,EAAE,GAAG,KAAK,iBAAiB,GAAG,SAAS,CAAC"}
|