Skip to content

Commit 4fe236f

Browse files
author
Luca Forstner
committed
ref: Clean up new integrations API and pave migration path
1 parent 2171633 commit 4fe236f

File tree

3 files changed

+84
-45
lines changed

3 files changed

+84
-45
lines changed

packages/core/src/integration.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Client, Event, EventHint, Integration, IntegrationFn, Options } from '@sentry/types';
1+
import type { Client, Event, EventHint, Integration, IntegrationFn, IntegrfiationClass, Options } from '@sentry/types';
22
import { arrayify, logger } from '@sentry/utils';
33

44
import { DEBUG_BUILD } from './debug-build';
@@ -184,3 +184,11 @@ export function convertIntegrationFnToClass<Fn extends IntegrationFn>(
184184
new (...args: Parameters<Fn>): Integration & ReturnType<Fn>;
185185
};
186186
}
187+
188+
/**
189+
* Utility function to aid with creating Sentry SDK integrations.
190+
*/
191+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
192+
export function defineSentryIntegration<F extends (...args: any[]) => Integration>(integrationFactory: F): F {
193+
return integrationFactory;
194+
}
Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,48 @@
1-
import type { IntegrationFn, WrappedFunction } from '@sentry/types';
1+
import type { Integration, WrappedFunction } from '@sentry/types';
22
import { getOriginalFunction } from '@sentry/utils';
3-
import { convertIntegrationFnToClass } from '../integration';
3+
import { defineSentryIntegration } from '../integration';
44

55
let originalFunctionToString: () => void;
66

77
const INTEGRATION_NAME = 'FunctionToString';
88

9-
const functionToStringIntegration: IntegrationFn = () => {
10-
return {
11-
name: INTEGRATION_NAME,
12-
setupOnce() {
13-
// eslint-disable-next-line @typescript-eslint/unbound-method
14-
originalFunctionToString = Function.prototype.toString;
15-
16-
// intrinsics (like Function.prototype) might be immutable in some environments
17-
// e.g. Node with --frozen-intrinsics, XS (an embedded JavaScript engine) or SES (a JavaScript proposal)
18-
try {
19-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20-
Function.prototype.toString = function (this: WrappedFunction, ...args: any[]): string {
21-
const context = getOriginalFunction(this) || this;
22-
return originalFunctionToString.apply(context, args);
23-
};
24-
} catch {
25-
// ignore errors here, just don't patch this
26-
}
27-
},
28-
};
29-
};
30-
31-
/** Patch toString calls to return proper name for wrapped functions */
32-
// eslint-disable-next-line deprecation/deprecation
33-
export const FunctionToString = convertIntegrationFnToClass(INTEGRATION_NAME, functionToStringIntegration);
9+
/**
10+
* Patch toString calls to return proper name for wrapped functions
11+
*/
12+
export const functionToStringIntegration = defineSentryIntegration(() => {
13+
// eslint-disable-next-line deprecation/deprecation
14+
return new FunctionToString();
15+
});
16+
17+
/**
18+
* Patch toString calls to return proper name for wrapped functions
19+
*
20+
* @deprecated Use `functionToStringIntegration()` instead.
21+
*/
22+
export class FunctionToString implements Integration {
23+
public static id = INTEGRATION_NAME;
24+
25+
public name: typeof INTEGRATION_NAME;
26+
27+
public constructor() {
28+
this.name = INTEGRATION_NAME;
29+
}
30+
31+
// eslint-disable-next-line jsdoc/require-jsdoc
32+
public setupOnce(): void {
33+
// eslint-disable-next-line @typescript-eslint/unbound-method
34+
originalFunctionToString = Function.prototype.toString;
35+
36+
// intrinsics (like Function.prototype) might be immutable in some environments
37+
// e.g. Node with --frozen-intrinsics, XS (an embedded JavaScript engine) or SES (a JavaScript proposal)
38+
try {
39+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
40+
Function.prototype.toString = function (this: WrappedFunction, ...args: any[]): string {
41+
const context = getOriginalFunction(this) || this;
42+
return originalFunctionToString.apply(context, args);
43+
};
44+
} catch {
45+
// ignore errors here, just don't patch this
46+
}
47+
}
48+
}

packages/core/src/integrations/inboundfilters.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import type { Event, IntegrationFn, StackFrame } from '@sentry/types';
1+
/* eslint-disable jsdoc/require-jsdoc */
2+
import type { Client, Event, EventHint, Integration, StackFrame } from '@sentry/types';
23
import { getEventDescription, logger, stringMatchesSomePattern } from '@sentry/utils';
34

45
import { DEBUG_BUILD } from '../debug-build';
5-
import { convertIntegrationFnToClass } from '../integration';
6+
import { defineSentryIntegration } from '../integration';
67

78
// "Script error." is hard coded into browsers for errors that it can't read.
89
// this is the result of a script being pulled in from an external domain and CORS.
@@ -30,22 +31,37 @@ export interface InboundFiltersOptions {
3031
}
3132

3233
const INTEGRATION_NAME = 'InboundFilters';
33-
const inboundFiltersIntegration: IntegrationFn = (options: Partial<InboundFiltersOptions>) => {
34-
return {
35-
name: INTEGRATION_NAME,
36-
// TODO v8: Remove this
37-
setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
38-
processEvent(event, _hint, client) {
39-
const clientOptions = client.getOptions();
40-
const mergedOptions = _mergeOptions(options, clientOptions);
41-
return _shouldDropEvent(event, mergedOptions) ? null : event;
42-
},
43-
};
44-
};
4534

46-
/** Inbound filters configurable by the user */
47-
// eslint-disable-next-line deprecation/deprecation
48-
export const InboundFilters = convertIntegrationFnToClass(INTEGRATION_NAME, inboundFiltersIntegration);
35+
export const inboundFiltersIntegration = defineSentryIntegration((options: Partial<InboundFiltersOptions>) => {
36+
// eslint-disable-next-line deprecation/deprecation
37+
return new InboundFilters(options);
38+
});
39+
40+
/**
41+
* Inbound filters configurable by the user
42+
*
43+
* @deprecated Use `inboundFiltersIntegration()` instead.
44+
*/
45+
export class InboundFilters implements Integration {
46+
public static id = INTEGRATION_NAME;
47+
48+
public name: string;
49+
50+
public constructor(private _options: Partial<InboundFiltersOptions>) {
51+
this.name = INTEGRATION_NAME;
52+
}
53+
54+
// TODO v8: Remove this
55+
public setupOnce(): void {
56+
// noop
57+
}
58+
59+
public preprocessEvent(event: Event, hint: EventHint | undefined, client: Client): Event | null {
60+
const clientOptions = client.getOptions();
61+
const mergedOptions = _mergeOptions(this._options, clientOptions);
62+
return _shouldDropEvent(event, mergedOptions) ? null : event;
63+
}
64+
}
4965

5066
function _mergeOptions(
5167
internalOptions: Partial<InboundFiltersOptions> = {},

0 commit comments

Comments
 (0)