From 351b5e2b293fd974b4c5661607f2d04e226ae232 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 26 Nov 2024 13:12:33 +0000 Subject: [PATCH 1/3] feat: Deprecate `registerEsmLoaderHooks.include` and `registerEsmLoaderHooks.exclude` --- docs/migration/draft-v9-migration-guide.md | 2 ++ packages/node/src/sdk/initOtel.ts | 4 ++- packages/node/src/types.ts | 32 ++++++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/docs/migration/draft-v9-migration-guide.md b/docs/migration/draft-v9-migration-guide.md index 6fc1f5e60f0e..579d99d0d9a3 100644 --- a/docs/migration/draft-v9-migration-guide.md +++ b/docs/migration/draft-v9-migration-guide.md @@ -88,3 +88,5 @@ If you are relying on `undefined` being passed in and having tracing enabled bec - Deprecated `processThreadBreadcrumbIntegration` in favor of `childProcessIntegration`. Functionally they are the same. - Deprecated `nestIntegration`. Use the NestJS SDK (`@sentry/nestjs`) instead. - Deprecated `setupNestErrorHandler`. Use the NestJS SDK (`@sentry/nestjs`) instead. +- Deprecated `registerEsmLoaderHooks.include` and `registerEsmLoaderHooks.exclude`. Set `onlyIncludeInstrumentedModules: true` instead. +- `registerEsmLoaderHooks` will only accept `true | false | undefined` in the future. The SDK will default to wrapping modules that are used as part of OpenTelemetry Instrumentation. diff --git a/packages/node/src/sdk/initOtel.ts b/packages/node/src/sdk/initOtel.ts index fd37e5ef477f..b731ecd8a332 100644 --- a/packages/node/src/sdk/initOtel.ts +++ b/packages/node/src/sdk/initOtel.ts @@ -42,10 +42,12 @@ interface RegisterOptions { } function getRegisterOptions(esmHookConfig?: EsmLoaderHookOptions): RegisterOptions { + // TODO(v9): Make onlyIncludeInstrumentedModules: true the default behavior. if (esmHookConfig?.onlyIncludeInstrumentedModules) { const { addHookMessagePort } = createAddHookMessageChannel(); // If the user supplied include, we need to use that as a starting point or use an empty array to ensure no modules // are wrapped if they are not hooked + // eslint-disable-next-line deprecation/deprecation return { data: { addHookMessagePort, include: esmHookConfig.include || [] }, transferList: [addHookMessagePort] }; } @@ -75,7 +77,7 @@ export function maybeInitializeEsmLoader(esmHookConfig?: EsmLoaderHookOptions): consoleSandbox(() => { // eslint-disable-next-line no-console console.warn( - '[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or use version 7.x of the Sentry Node.js SDK.', + '[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.', ); }); } diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index 7235e2057c34..072ea0b5d53e 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -1,12 +1,30 @@ import type { Span as WriteableSpan } from '@opentelemetry/api'; +import type { Instrumentation } from '@opentelemetry/instrumentation'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import type { ClientOptions, Options, SamplingContext, Scope, Span, TracePropagationTargets } from '@sentry/types'; import type { NodeTransportOptions } from './transports'; +/** + * Note: In the next major version of the Sentry SDK this interface will be removed and the SDK will by default only wrap + * ESM modules that are required to be wrapped by OpenTelemetry Instrumentation. + */ export interface EsmLoaderHookOptions { + /** + * Provide a list of modules to wrap with `import-in-the-middle`. + * + * @deprecated It is recommended to use `onlyIncludeInstrumentedModules: true` instead of manually defining modules to include and exclude. + */ include?: Array; - exclude?: Array /** + + /** + * Provide a list of modules to prevent them from being wrapped with `import-in-the-middle`. + * + * @deprecated It is recommended to use `onlyIncludeInstrumentedModules: true` instead of manually defining modules to include and exclude. + */ + exclude?: Array; + + /** * When set to `true`, `import-in-the-middle` will only wrap ESM modules that are specifically instrumented by * OpenTelemetry plugins. This is useful to avoid issues where `import-in-the-middle` is not compatible with some of * your dependencies. @@ -16,7 +34,11 @@ export interface EsmLoaderHookOptions { * `Sentry.init()`. * * Defaults to `false`. - */; + * + * Note: In the next major version of the Sentry SDK this option will be removed and the SDK will by default only wrap + * ESM modules that are required to be wrapped by OpenTelemetry Instrumentation. + */ + // TODO(v9): Make `onlyIncludeInstrumentedModules: true` the default behavior. onlyIncludeInstrumentedModules?: boolean; } @@ -87,6 +109,8 @@ export interface BaseNodeOptions { * * The `SentryPropagator` * * The `SentryContextManager` * * The `SentrySampler` + * + * If you are registering your own OpenTelemetry Loader Hooks (or `import-in-the-middle` hooks), it is also recommended to set the `registerEsmLoaderHooks` option to false. */ skipOpenTelemetrySetup?: boolean; @@ -117,7 +141,11 @@ export interface BaseNodeOptions { * ``` * * Defaults to `true`. + * + * Note: In the next major version of the SDK, the possibility to provide fine-grained control will be removed from this option. + * This means that it will only be possible to pass `true` or `false`. The default value will continue to be `true`. */ + // TODO(v9): Only accept true | false | undefined. registerEsmLoaderHooks?: boolean | EsmLoaderHookOptions; /** From 0a16b123504dcdf875e8e5b1cd41c8189fe21acb Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 26 Nov 2024 13:14:59 +0000 Subject: [PATCH 2/3] lint --- packages/node/src/types.ts | 1 - packages/nuxt/src/server/sdk.ts | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index 072ea0b5d53e..05dfd7949b00 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -1,5 +1,4 @@ import type { Span as WriteableSpan } from '@opentelemetry/api'; -import type { Instrumentation } from '@opentelemetry/instrumentation'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import type { ClientOptions, Options, SamplingContext, Scope, Span, TracePropagationTargets } from '@sentry/types'; diff --git a/packages/nuxt/src/server/sdk.ts b/packages/nuxt/src/server/sdk.ts index 6c4dd4712a1a..ccef93ea3350 100644 --- a/packages/nuxt/src/server/sdk.ts +++ b/packages/nuxt/src/server/sdk.ts @@ -100,9 +100,12 @@ export function mergeRegisterEsmLoaderHooks( ): SentryNuxtServerOptions['registerEsmLoaderHooks'] { if (typeof options.registerEsmLoaderHooks === 'object' && options.registerEsmLoaderHooks !== null) { return { + // eslint-disable-next-line deprecation/deprecation exclude: Array.isArray(options.registerEsmLoaderHooks.exclude) - ? [...options.registerEsmLoaderHooks.exclude, /vue/] - : options.registerEsmLoaderHooks.exclude ?? [/vue/], + ? // eslint-disable-next-line deprecation/deprecation + [...options.registerEsmLoaderHooks.exclude, /vue/] + : // eslint-disable-next-line deprecation/deprecation + options.registerEsmLoaderHooks.exclude ?? [/vue/], }; } return options.registerEsmLoaderHooks ?? { exclude: [/vue/] }; From be8df7d2966eefe7c3162e3d50434535d7ee61dd Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 26 Nov 2024 13:58:05 +0000 Subject: [PATCH 3/3] test --- dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts b/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts index 25f90460e2b9..f8d752497d46 100644 --- a/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts +++ b/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts @@ -5,7 +5,7 @@ afterAll(() => { }); const esmWarning = - '[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or use version 7.x of the Sentry Node.js SDK.'; + '[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.'; test("warns if using ESM on Node.js versions that don't support `register()`", async () => { const nodeMajorVersion = Number(process.versions.node.split('.')[0]);