Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 8 additions & 26 deletions packages/cloudflare/src/baseSdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,10 @@ function getRegisteredChannelIntegrations(): Integration[] {
}

/**
* Get the default integrations that run on any Workers-compatible runtime, i.e. without the
* `nodejs_compat` compatibility flag.
*
* `getDefaultIntegrations` in `sdk.ts` extends this set with the integrations that do depend on
* Node.js APIs. Keeping the two apart is what allows `wrapRequestHandler` to stay usable on runtimes
* that cannot enable `nodejs_compat`, such as Shopify Oxygen.
* Get the default integrations for the Cloudflare SDK.
* These also work on Workers-compatible runtimes without the `nodejs_compat` compatibility flag.
*/
export function getBaseDefaultIntegrations(options: CloudflareOptions): Integration[] {
export function getDefaultIntegrations(options: CloudflareOptions): Integration[] {
return [
// The Dedupe integration should not be used in workflows because we want to
// capture all step failures, even if they are the same error.
Expand All @@ -72,12 +68,10 @@ export function getBaseDefaultIntegrations(options: CloudflareOptions): Integrat
}

/**
* Initializes the Cloudflare SDK with the passed default integrations.
* Initializes the Cloudflare SDK without setting up an OpenTelemetry tracer provider.
*
* The default integrations are injected rather than imported so that this module stays free of
* Node.js-only code. `request.ts` — which backs both `wrapRequestHandler` and the
* `@sentry/cloudflare/request` entry point, and therefore has to work on runtimes without the
* `nodejs_compat` compatibility flag — creates its client from here instead of from `sdk.ts`.
* Kept separate from `sdk.ts` so `@sentry/cloudflare/request` can load without Node.js-only
* dependencies on runtimes such as Shopify Oxygen.
*
* The client is cached and reused across invocations within the same isolate,
* unless `cacheClient: false` is passed. This avoids the
Expand All @@ -87,10 +81,7 @@ export function getBaseDefaultIntegrations(options: CloudflareOptions): Integrat
* boundary that reliably extends execution, so spans/events that end after
* disposal would otherwise be lost.
*/
export function initWithDefaultIntegrations(
options: CloudflareOptions,
getDefaultIntegrationsImpl: (options: CloudflareOptions) => Integration[],
): CloudflareClient | undefined {
export function initBaseSdk(options: CloudflareOptions): CloudflareClient | undefined {
const cached = getCachedClient();
const cacheEnabled = options.cacheClient !== false;

Expand All @@ -111,7 +102,7 @@ export function initWithDefaultIntegrations(
// included, unless an SDK built the list from the defaults.
const usesSdkDefaults = options.defaultIntegrations === undefined || !!options._extendsDefaultIntegrations;
if (options.defaultIntegrations === undefined) {
options.defaultIntegrations = getDefaultIntegrationsImpl(options);
options.defaultIntegrations = getDefaultIntegrations(options);
}

// A cached client outlives any single invocation, so binding it to one
Expand Down Expand Up @@ -191,12 +182,3 @@ export function initWithDefaultIntegrations(

return client;
}

/**
* Initializes the Cloudflare SDK with only the default integrations from
* {@link getBaseDefaultIntegrations}, i.e. those that work without the `nodejs_compat`
* compatibility flag.
*/
export function initBaseSdk(options: CloudflareOptions): CloudflareClient | undefined {
return initWithDefaultIntegrations(options, getBaseDefaultIntegrations);
}
7 changes: 3 additions & 4 deletions packages/cloudflare/src/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import { type RequestHandlerWrapperOptions, wrapRequestHandlerWithInit } from '.
/**
* Wraps a cloudflare request handler in Sentry instrumentation.
*
* The client is set up with the default integrations that work without the `nodejs_compat`
* compatibility flag, so that this also works on runtimes that cannot enable it (e.g. Shopify
* Oxygen). On a runtime that has `nodejs_compat`, pass `defaultIntegrations:
* getDefaultIntegrations(options)` in `options` to get the full set instead.
* The client uses the same default integrations as `init`, without setting up an OpenTelemetry
* tracer provider. This entry point also works on runtimes that cannot enable the `nodejs_compat`
* compatibility flag, such as Shopify Oxygen.
*/
export function wrapRequestHandler(
wrapperOptions: Omit<RequestHandlerWrapperOptions, 'options'> & {
Expand Down
17 changes: 5 additions & 12 deletions packages/cloudflare/src/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import type { Integration } from '@sentry/core';
import { getBaseDefaultIntegrations, initWithDefaultIntegrations } from './baseSdk';
import { initBaseSdk } from './baseSdk';
import type { CloudflareClient, CloudflareOptions } from './client';
import { setupOpenTelemetryTracer } from './opentelemetry/tracer';
import { type RequestHandlerWrapperOptions, wrapRequestHandlerWithInit } from './wrapRequestHandlerWithInit';

// Test-only helper, re-exported here so tests can reset the global client cache.
export { _clearGlobalClientCache } from './clientCache';

/**
* Get the default integrations for the Cloudflare SDK.
*/
export function getDefaultIntegrations(options: CloudflareOptions): Integration[] {
return getBaseDefaultIntegrations(options);
}
export { getDefaultIntegrations } from './baseSdk';

/**
* Initializes the cloudflare SDK.
Expand All @@ -28,13 +22,12 @@ export function init(options: CloudflareOptions): CloudflareClient | undefined {
setupOpenTelemetryTracer();
}

return initWithDefaultIntegrations(options, getDefaultIntegrations);
return initBaseSdk(options);
}

/**
* `wrapRequestHandler` backed by `init`, so the request gets the full default integrations and
* honors `enableOpenTelemetrySetup`. The `@sentry/cloudflare/request` variant deliberately skips
* both to stay usable without `nodejs_compat`.
* `wrapRequestHandler` backed by `init`, so the request honors `enableOpenTelemetrySetup`. The
* `@sentry/cloudflare/request` variant deliberately skips it to stay usable without `nodejs_compat`.
*
* For framework SDKs building on the main entry point, e.g. SvelteKit, whose OpenTelemetry spans
* need the tracer provider.
Expand Down
2 changes: 1 addition & 1 deletion packages/cloudflare/src/wrapRequestHandlerWithInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type InitSdk = (options: CloudflareOptions) => CloudflareClient | undefined;
* Same as {@link wrapRequestHandler}, but with the SDK initialization injected.
*
* Wrappers that are only reachable from the main entry point — where `nodejs_compat` is a
* requirement anyway — pass `init` from `sdk.ts` to get the full default integrations.
* requirement anyway — pass `init` from `sdk.ts` so `enableOpenTelemetrySetup` is honored.
*
* @internal
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/cloudflare/test/requestModuleGraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('module graph of `wrapRequestHandler`', () => {
expect(modules).not.toContain('async.ts');
});

it('does not reach `sdk.ts`, which holds the default integrations that need `nodejs_compat`', () => {
it('does not reach `sdk.ts`, which imports the OpenTelemetry tracer setup', () => {
expect(modules).not.toContain('sdk.ts');
});
});
Loading