Skip to content

Commit 01e552c

Browse files
committed
feat(node): Expose functional integrations to replace classes
We'll need to adjust the http & undici options a bit to align with otel integrations, but we can do this in a follow up, otherwise this will become a bit unwieldly...
1 parent 20d11cd commit 01e552c

25 files changed

+242
-100
lines changed

packages/node/src/index.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,22 +122,36 @@ import * as Handlers from './handlers';
122122
import * as NodeIntegrations from './integrations';
123123
import * as TracingIntegrations from './tracing/integrations';
124124

125-
const INTEGRATIONS = {
125+
/** @deprecated Import the integration function directly, e.g. `inboundFiltersIntegration()` instead of `new Integrations.InboundFilter(). */
126+
export const Integrations = {
126127
// eslint-disable-next-line deprecation/deprecation
127128
...CoreIntegrations,
128129
...NodeIntegrations,
129130
...TracingIntegrations,
130131
};
131132

133+
export { consoleIntegration } from './integrations/console';
134+
export { onUncaughtExceptionIntegration } from './integrations/onuncaughtexception';
135+
export { onUnhandledRejectionIntegration } from './integrations/onunhandledrejection';
136+
export { modulesIntegration } from './integrations/modules';
137+
export { contextLinesIntegration } from './integrations/contextlines';
138+
export { nodeContextIntegration } from './integrations/context';
139+
export { localVariablesIntegration } from './integrations/local-variables';
140+
export { spotlightIntegration } from './integrations/spotlight';
141+
export { anrIntegration } from './integrations/anr';
142+
export { hapiIntegration } from './integrations/hapi';
143+
// eslint-disable-next-line deprecation/deprecation
144+
export { Undici, undiciIntegration } from './integrations/undici';
145+
// eslint-disable-next-line deprecation/deprecation
146+
export { Http, httpIntegration } from './integrations/http';
147+
132148
// TODO(v8): Remove all of these exports. They were part of a hotfix #10339 where we produced wrong .d.ts files because we were packing packages inside the /build folder.
133149
export type { LocalVariablesIntegrationOptions } from './integrations/local-variables/common';
134150
export type { DebugSession } from './integrations/local-variables/local-variables-sync';
135151
export type { AnrIntegrationOptions } from './integrations/anr/common';
136-
export { Undici } from './integrations/undici';
137-
export { Http } from './integrations/http';
138152
// ---
139153

140-
export { INTEGRATIONS as Integrations, Handlers };
154+
export { Handlers };
141155

142156
export { hapiErrorPlugin } from './integrations/hapi';
143157

packages/node/src/integrations/anr/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// TODO (v8): This import can be removed once we only support Node with global URL
22
import { URL } from 'url';
3-
import { convertIntegrationFnToClass, getCurrentScope } from '@sentry/core';
3+
import { convertIntegrationFnToClass, defineIntegration, getCurrentScope } from '@sentry/core';
44
import type { Client, Contexts, Event, EventHint, Integration, IntegrationClass, IntegrationFn } from '@sentry/types';
55
import { dynamicRequire, logger } from '@sentry/utils';
66
import type { Worker, WorkerOptions } from 'worker_threads';
@@ -52,7 +52,7 @@ interface InspectorApi {
5252

5353
const INTEGRATION_NAME = 'Anr';
5454

55-
const anrIntegration = ((options: Partial<AnrIntegrationOptions> = {}) => {
55+
const _anrIntegration = ((options: Partial<AnrIntegrationOptions> = {}) => {
5656
return {
5757
name: INTEGRATION_NAME,
5858
// TODO v8: Remove this
@@ -68,10 +68,14 @@ const anrIntegration = ((options: Partial<AnrIntegrationOptions> = {}) => {
6868
};
6969
}) satisfies IntegrationFn;
7070

71+
export const anrIntegration = defineIntegration(_anrIntegration);
72+
7173
/**
7274
* Starts a thread to detect App Not Responding (ANR) events
7375
*
7476
* ANR detection requires Node 16.17.0 or later
77+
*
78+
* @deprecated Use `anrIntegration()` instead.
7579
*/
7680
// eslint-disable-next-line deprecation/deprecation
7781
export const Anr = convertIntegrationFnToClass(INTEGRATION_NAME, anrIntegration) as IntegrationClass<
@@ -80,6 +84,9 @@ export const Anr = convertIntegrationFnToClass(INTEGRATION_NAME, anrIntegration)
8084
new (options?: Partial<AnrIntegrationOptions>): Integration & { setup(client: Client): void };
8185
};
8286

87+
// eslint-disable-next-line deprecation/deprecation
88+
export type Anr = typeof Anr;
89+
8390
/**
8491
* Starts the ANR worker thread
8592
*/

packages/node/src/integrations/anr/legacy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ interface LegacyOptions {
2626
*/
2727
export function enableAnrDetection(options: Partial<LegacyOptions>): Promise<void> {
2828
const client = getClient() as NodeClient;
29+
// eslint-disable-next-line deprecation/deprecation
2930
const integration = new Anr(options);
3031
integration.setup(client);
3132
return Promise.resolve();

packages/node/src/integrations/console.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as util from 'util';
2-
import { addBreadcrumb, convertIntegrationFnToClass, getClient } from '@sentry/core';
2+
import { addBreadcrumb, convertIntegrationFnToClass, defineIntegration, getClient } from '@sentry/core';
33
import type { Client, Integration, IntegrationClass, IntegrationFn } from '@sentry/types';
44
import { addConsoleInstrumentationHandler, severityLevelFromString } from '@sentry/utils';
55

66
const INTEGRATION_NAME = 'Console';
77

8-
const consoleIntegration = (() => {
8+
const _consoleIntegration = (() => {
99
return {
1010
name: INTEGRATION_NAME,
1111
// TODO v8: Remove this
@@ -32,8 +32,16 @@ const consoleIntegration = (() => {
3232
};
3333
}) satisfies IntegrationFn;
3434

35-
/** Console module integration */
35+
export const consoleIntegration = defineIntegration(_consoleIntegration);
36+
37+
/**
38+
* Console module integration.
39+
* @deprecated Use `consoleIntegration()` instead.
40+
*/
3641
// eslint-disable-next-line deprecation/deprecation
3742
export const Console = convertIntegrationFnToClass(INTEGRATION_NAME, consoleIntegration) as IntegrationClass<
3843
Integration & { setup: (client: Client) => void }
3944
>;
45+
46+
// eslint-disable-next-line deprecation/deprecation
47+
export type Console = typeof Console;

packages/node/src/integrations/context.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { readFile, readdir } from 'fs';
44
import * as os from 'os';
55
import { join } from 'path';
66
import { promisify } from 'util';
7-
import { convertIntegrationFnToClass } from '@sentry/core';
7+
import { convertIntegrationFnToClass, defineIntegration } from '@sentry/core';
88
import type {
99
AppContext,
1010
CloudResourceContext,
@@ -37,7 +37,7 @@ interface ContextOptions {
3737
cloudResource?: boolean;
3838
}
3939

40-
const nodeContextIntegration = ((options: ContextOptions = {}) => {
40+
const _nodeContextIntegration = ((options: ContextOptions = {}) => {
4141
let cachedContext: Promise<Contexts> | undefined;
4242

4343
const _options = {
@@ -110,7 +110,12 @@ const nodeContextIntegration = ((options: ContextOptions = {}) => {
110110
};
111111
}) satisfies IntegrationFn;
112112

113-
/** Add node modules / packages to the event */
113+
export const nodeContextIntegration = defineIntegration(_nodeContextIntegration);
114+
115+
/**
116+
* Add node modules / packages to the event.
117+
* @deprecated Use `nodeContextIntegration()` instead.
118+
*/
114119
// eslint-disable-next-line deprecation/deprecation
115120
export const Context = convertIntegrationFnToClass(INTEGRATION_NAME, nodeContextIntegration) as IntegrationClass<
116121
Integration & { processEvent: (event: Event) => Promise<Event> }
@@ -124,6 +129,9 @@ export const Context = convertIntegrationFnToClass(INTEGRATION_NAME, nodeContext
124129
}): Integration;
125130
};
126131

132+
// eslint-disable-next-line deprecation/deprecation
133+
export type Context = typeof Context;
134+
127135
/**
128136
* Updates the context with dynamic values that can change
129137
*/

packages/node/src/integrations/contextlines.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { readFile } from 'fs';
2-
import { convertIntegrationFnToClass } from '@sentry/core';
2+
import { convertIntegrationFnToClass, defineIntegration } from '@sentry/core';
33
import type { Event, Integration, IntegrationClass, IntegrationFn, StackFrame } from '@sentry/types';
44
import { LRUMap, addContextToFrame } from '@sentry/utils';
55

@@ -35,7 +35,7 @@ interface ContextLinesOptions {
3535
frameContextLines?: number;
3636
}
3737

38-
const contextLinesIntegration = ((options: ContextLinesOptions = {}) => {
38+
const _contextLinesIntegration = ((options: ContextLinesOptions = {}) => {
3939
const contextLines = options.frameContextLines !== undefined ? options.frameContextLines : DEFAULT_LINES_OF_CONTEXT;
4040

4141
return {
@@ -48,7 +48,12 @@ const contextLinesIntegration = ((options: ContextLinesOptions = {}) => {
4848
};
4949
}) satisfies IntegrationFn;
5050

51-
/** Add node modules / packages to the event */
51+
export const contextLinesIntegration = defineIntegration(_contextLinesIntegration);
52+
53+
/**
54+
* Add node modules / packages to the event.
55+
* @deprecated Use `contextLinesIntegration()` instead.
56+
*/
5257
// eslint-disable-next-line deprecation/deprecation
5358
export const ContextLines = convertIntegrationFnToClass(INTEGRATION_NAME, contextLinesIntegration) as IntegrationClass<
5459
Integration & { processEvent: (event: Event) => Promise<Event> }
@@ -119,6 +124,9 @@ function addSourceContextToFrames(frames: StackFrame[], contextLines: number): v
119124
}
120125
}
121126

127+
// eslint-disable-next-line deprecation/deprecation
128+
export type ContextLines = typeof ContextLines;
129+
122130
/**
123131
* Reads file contents and caches them in a global LRU cache.
124132
* If reading fails, mark the file as null in the cache so we don't try again.

packages/node/src/integrations/hapi/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
captureException,
44
continueTrace,
55
convertIntegrationFnToClass,
6+
defineIntegration,
67
getActiveTransaction,
78
getCurrentScope,
89
getDynamicSamplingContextFromSpan,
@@ -139,7 +140,7 @@ export type HapiOptions = {
139140

140141
const INTEGRATION_NAME = 'Hapi';
141142

142-
const hapiIntegration = ((options: HapiOptions = {}) => {
143+
const _hapiIntegration = ((options: HapiOptions = {}) => {
143144
const server = options.server as undefined | Server;
144145

145146
return {
@@ -161,8 +162,14 @@ const hapiIntegration = ((options: HapiOptions = {}) => {
161162
};
162163
}) satisfies IntegrationFn;
163164

165+
export const hapiIntegration = defineIntegration(_hapiIntegration);
166+
164167
/**
165-
* Hapi Framework Integration
168+
* Hapi Framework Integration.
169+
* @deprecated Use `hapiIntegration()` instead.
166170
*/
167171
// eslint-disable-next-line deprecation/deprecation
168172
export const Hapi = convertIntegrationFnToClass(INTEGRATION_NAME, hapiIntegration);
173+
174+
// eslint-disable-next-line deprecation/deprecation
175+
export type Hapi = typeof Hapi;

packages/node/src/integrations/http.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type * as http from 'http';
22
import type * as https from 'https';
33
import type { Hub } from '@sentry/core';
4-
import { getIsolationScope } from '@sentry/core';
4+
import { getIsolationScope, defineIntegration } from '@sentry/core';
55
import {
66
addBreadcrumb,
77
getActiveSpan,
@@ -15,7 +15,15 @@ import {
1515
spanToJSON,
1616
spanToTraceHeader,
1717
} from '@sentry/core';
18-
import type { EventProcessor, Integration, SanitizedRequestData, TracePropagationTargets } from '@sentry/types';
18+
import type {
19+
DynamicSamplingContext,
20+
EventProcessor,
21+
Integration,
22+
IntegrationFn,
23+
IntegrationFnResult,
24+
SanitizedRequestData,
25+
TracePropagationTargets,
26+
} from '@sentry/types';
1927
import {
2028
LRUMap,
2129
dynamicSamplingContextToSentryBaggageHeader,
@@ -72,9 +80,18 @@ interface HttpOptions {
7280
tracing?: TracingOptions | boolean;
7381
}
7482

83+
const _httpIntegration = ((options?: HttpOptions) => {
84+
// eslint-disable-next-line deprecation/deprecation
85+
return new Http(options) as unknown as IntegrationFnResult;
86+
}) satisfies IntegrationFn;
87+
88+
export const httpIntegration = defineIntegration(_httpIntegration);
89+
7590
/**
7691
* The http module integration instruments Node's internal http module. It creates breadcrumbs, transactions for outgoing
7792
* http requests and attaches trace data when tracing is enabled via its `tracing` option.
93+
*
94+
* @deprecated Use `httpIntegration()` instead.
7895
*/
7996
export class Http implements Integration {
8097
/**
@@ -85,6 +102,7 @@ export class Http implements Integration {
85102
/**
86103
* @inheritDoc
87104
*/
105+
// eslint-disable-next-line deprecation/deprecation
88106
public name: string = Http.id;
89107

90108
private readonly _breadcrumbs: boolean;

packages/node/src/integrations/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
/* eslint-disable deprecation/deprecation */
12
export { Console } from './console';
23
export { Http } from './http';
34
export { OnUncaughtException } from './onuncaughtexception';
45
export { OnUnhandledRejection } from './onunhandledrejection';
56
export { Modules } from './modules';
67
export { ContextLines } from './contextlines';
78
export { Context } from './context';
8-
// eslint-disable-next-line deprecation/deprecation
99
export { RequestData } from '@sentry/core';
1010
export { LocalVariables } from './local-variables';
1111
export { Undici } from './undici';
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
import { LocalVariablesSync } from './local-variables-sync';
1+
import { LocalVariablesSync, localVariablesSyncIntegration } from './local-variables-sync';
22

33
/**
4-
* Adds local variables to exception frames
4+
* Adds local variables to exception frames.
5+
*
6+
* @deprecated Use `localVariablesIntegration()` instead.
57
*/
8+
// eslint-disable-next-line deprecation/deprecation
69
export const LocalVariables = LocalVariablesSync;
10+
// eslint-disable-next-line deprecation/deprecation
11+
export type LocalVariables = LocalVariablesSync;
12+
13+
export const localVariablesIntegration = localVariablesSyncIntegration;

packages/node/src/integrations/local-variables/local-variables-async.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Session } from 'node:inspector/promises';
2-
import { convertIntegrationFnToClass } from '@sentry/core';
2+
import { convertIntegrationFnToClass, defineIntegration } from '@sentry/core';
33
import type { Event, Exception, Integration, IntegrationClass, IntegrationFn, StackParser } from '@sentry/types';
44
import { LRUMap, dynamicRequire, logger } from '@sentry/utils';
55
import type { Debugger, InspectorNotification, Runtime } from 'inspector';
@@ -76,7 +76,7 @@ const INTEGRATION_NAME = 'LocalVariablesAsync';
7676
/**
7777
* Adds local variables to exception frames
7878
*/
79-
const localVariablesAsyncIntegration = ((options: LocalVariablesIntegrationOptions = {}) => {
79+
const _localVariablesAsyncIntegration = ((options: LocalVariablesIntegrationOptions = {}) => {
8080
const cachedFrames: LRUMap<string, FrameVariables[]> = new LRUMap(20);
8181
let rateLimiter: RateLimitIncrement | undefined;
8282
let shouldProcessEvent = false;
@@ -253,11 +253,17 @@ const localVariablesAsyncIntegration = ((options: LocalVariablesIntegrationOptio
253253
};
254254
}) satisfies IntegrationFn;
255255

256+
export const localVariablesAsyncIntegration = defineIntegration(_localVariablesAsyncIntegration);
257+
256258
/**
257-
* Adds local variables to exception frames
259+
* Adds local variables to exception frames.
260+
* @deprecated Use `localVariablesAsyncIntegration()` instead.
258261
*/
259262
// eslint-disable-next-line deprecation/deprecation
260263
export const LocalVariablesAsync = convertIntegrationFnToClass(
261264
INTEGRATION_NAME,
262265
localVariablesAsyncIntegration,
263266
) as IntegrationClass<Integration & { processEvent: (event: Event) => Event; setup: (client: NodeClient) => void }>;
267+
268+
// eslint-disable-next-line deprecation/deprecation
269+
export type LocalVariablesAsync = typeof LocalVariablesAsync;

packages/node/src/integrations/local-variables/local-variables-sync.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable max-lines */
2-
import { convertIntegrationFnToClass, getClient } from '@sentry/core';
2+
import { convertIntegrationFnToClass, defineIntegration, getClient } from '@sentry/core';
33
import type { Event, Exception, Integration, IntegrationClass, IntegrationFn, StackParser } from '@sentry/types';
44
import { LRUMap, logger } from '@sentry/utils';
55
import type { Debugger, InspectorNotification, Runtime, Session } from 'inspector';
@@ -219,7 +219,7 @@ const INTEGRATION_NAME = 'LocalVariables';
219219
/**
220220
* Adds local variables to exception frames
221221
*/
222-
const localVariablesSyncIntegration = ((
222+
const _localVariablesSyncIntegration = ((
223223
options: LocalVariablesIntegrationOptions = {},
224224
session: DebugSession | undefined = tryNewAsyncSession(),
225225
) => {
@@ -392,8 +392,11 @@ const localVariablesSyncIntegration = ((
392392
};
393393
}) satisfies IntegrationFn;
394394

395+
export const localVariablesSyncIntegration = defineIntegration(_localVariablesSyncIntegration);
396+
395397
/**
396-
* Adds local variables to exception frames
398+
* Adds local variables to exception frames.
399+
* @deprecated Use `localVariablesSyncIntegration()` instead.
397400
*/
398401
// eslint-disable-next-line deprecation/deprecation
399402
export const LocalVariablesSync = convertIntegrationFnToClass(
@@ -402,3 +405,6 @@ export const LocalVariablesSync = convertIntegrationFnToClass(
402405
) as IntegrationClass<Integration & { processEvent: (event: Event) => Event; setup: (client: NodeClient) => void }> & {
403406
new (options?: LocalVariablesIntegrationOptions, session?: DebugSession): Integration;
404407
};
408+
409+
// eslint-disable-next-line deprecation/deprecation
410+
export type LocalVariablesSync = typeof LocalVariablesSync;

0 commit comments

Comments
 (0)