Skip to content

Commit 62b438f

Browse files
committed
ref(integrations): Refactor pluggable integrations to use processEvent
1 parent 95e1801 commit 62b438f

File tree

7 files changed

+166
-183
lines changed

7 files changed

+166
-183
lines changed

packages/integrations/src/contextlines.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Event, EventProcessor, Hub, Integration, StackFrame } from '@sentry/types';
1+
import type { Event, Integration, StackFrame } from '@sentry/types';
22
import { addContextToFrame, GLOBAL_OBJ, stripUrlQueryAndFragment } from '@sentry/utils';
33

44
const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;
@@ -44,17 +44,20 @@ export class ContextLines implements Integration {
4444
/**
4545
* @inheritDoc
4646
*/
47-
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
48-
addGlobalEventProcessor(event => {
49-
const self = getCurrentHub().getIntegration(ContextLines);
50-
if (!self) {
51-
return event;
52-
}
53-
return this.addSourceContext(event);
54-
});
47+
public setupOnce(_addGlobaleventProcessor: unknown, _getCurrentHub: unknown): void {
48+
// noop
49+
}
50+
51+
/** @inheritDoc */
52+
public processEvent(event: Event): Event {
53+
return this.addSourceContext(event);
5554
}
5655

57-
/** Processes an event and adds context lines */
56+
/**
57+
* Processes an event and adds context lines.
58+
*
59+
* TODO (v8): Make this internal/private
60+
*/
5861
public addSourceContext(event: Event): Event {
5962
const doc = WINDOW.document;
6063
const htmlFilename = WINDOW.location && stripUrlQueryAndFragment(WINDOW.location.href);

packages/integrations/src/dedupe.ts

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Event, EventProcessor, Exception, Hub, Integration, StackFrame } from '@sentry/types';
1+
import type { Event, Exception, Integration, StackFrame } from '@sentry/types';
22
import { logger } from '@sentry/utils';
33

44
/** Deduplication filter */
@@ -22,36 +22,32 @@ export class Dedupe implements Integration {
2222
this.name = Dedupe.id;
2323
}
2424

25+
/** @inheritDoc */
26+
public setupOnce(_addGlobaleventProcessor: unknown, _getCurrentHub: unknown): void {
27+
// noop
28+
}
29+
2530
/**
2631
* @inheritDoc
2732
*/
28-
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
29-
const eventProcessor: EventProcessor = currentEvent => {
30-
// We want to ignore any non-error type events, e.g. transactions or replays
31-
// These should never be deduped, and also not be compared against as _previousEvent.
32-
if (currentEvent.type) {
33-
return currentEvent;
34-
}
33+
public processEvent(currentEvent: Event): Event | null {
34+
// We want to ignore any non-error type events, e.g. transactions or replays
35+
// These should never be deduped, and also not be compared against as _previousEvent.
36+
if (currentEvent.type) {
37+
return currentEvent;
38+
}
3539

36-
const self = getCurrentHub().getIntegration(Dedupe);
37-
if (self) {
38-
// Juuust in case something goes wrong
39-
try {
40-
if (_shouldDropEvent(currentEvent, self._previousEvent)) {
41-
__DEBUG_BUILD__ && logger.warn('Event dropped due to being a duplicate of previously captured event.');
42-
return null;
43-
}
44-
} catch (_oO) {
45-
return (self._previousEvent = currentEvent);
46-
}
47-
48-
return (self._previousEvent = currentEvent);
40+
// Juuust in case something goes wrong
41+
try {
42+
if (_shouldDropEvent(currentEvent, this._previousEvent)) {
43+
__DEBUG_BUILD__ && logger.warn('Event dropped due to being a duplicate of previously captured event.');
44+
return null;
4945
}
50-
return currentEvent;
51-
};
46+
} catch (_oO) {
47+
return (this._previousEvent = currentEvent);
48+
}
5249

53-
eventProcessor.id = this.name;
54-
addGlobalEventProcessor(eventProcessor);
50+
return (this._previousEvent = currentEvent);
5551
}
5652
}
5753

Lines changed: 77 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import type { Contexts, Event, EventHint, EventProcessor, ExtendedError, Hub, Integration } from '@sentry/types';
1+
import type { Contexts, Event, EventHint, ExtendedError, Integration } from '@sentry/types';
22
import { addNonEnumerableProperty, isError, isPlainObject, logger, normalize } from '@sentry/utils';
33

44
/** JSDoc */
55
interface ExtraErrorDataOptions {
6-
depth?: number;
6+
depth: number;
77
}
88

99
/** Patch toString calls to return proper name for wrapped functions */
@@ -24,7 +24,7 @@ export class ExtraErrorData implements Integration {
2424
/**
2525
* @inheritDoc
2626
*/
27-
public constructor(options?: ExtraErrorDataOptions) {
27+
public constructor(options?: Partial<ExtraErrorDataOptions>) {
2828
this.name = ExtraErrorData.id;
2929

3030
this._options = {
@@ -36,94 +36,99 @@ export class ExtraErrorData implements Integration {
3636
/**
3737
* @inheritDoc
3838
*/
39-
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
40-
addGlobalEventProcessor((event: Event, hint: EventHint) => {
41-
const self = getCurrentHub().getIntegration(ExtraErrorData);
42-
if (!self) {
43-
return event;
44-
}
45-
return self.enhanceEventWithErrorData(event, hint);
46-
});
39+
public setupOnce(_addGlobaleventProcessor: unknown, _getCurrentHub: unknown): void {
40+
// noop
41+
}
42+
43+
/** @inheritDoc */
44+
public processEvent(event: Event, hint: EventHint): Event {
45+
return this.enhanceEventWithErrorData(event, hint);
4746
}
4847

4948
/**
50-
* Attaches extracted information from the Error object to extra field in the Event
49+
* Attaches extracted information from the Error object to extra field in the Event.
50+
*
51+
* TODO (v8): Drop this public function.
5152
*/
5253
public enhanceEventWithErrorData(event: Event, hint: EventHint = {}): Event {
53-
if (!hint.originalException || !isError(hint.originalException)) {
54-
return event;
55-
}
56-
const exceptionName = (hint.originalException as ExtendedError).name || hint.originalException.constructor.name;
54+
return _enhanceEventWithErrorData(event, hint, this._options.depth);
55+
}
56+
}
5757

58-
const errorData = this._extractErrorData(hint.originalException as ExtendedError);
58+
function _enhanceEventWithErrorData(event: Event, hint: EventHint = {}, depth: number): Event {
59+
if (!hint.originalException || !isError(hint.originalException)) {
60+
return event;
61+
}
62+
const exceptionName = (hint.originalException as ExtendedError).name || hint.originalException.constructor.name;
5963

60-
if (errorData) {
61-
const contexts: Contexts = {
62-
...event.contexts,
63-
};
64+
const errorData = _extractErrorData(hint.originalException as ExtendedError);
6465

65-
const normalizedErrorData = normalize(errorData, this._options.depth);
66+
if (errorData) {
67+
const contexts: Contexts = {
68+
...event.contexts,
69+
};
6670

67-
if (isPlainObject(normalizedErrorData)) {
68-
// We mark the error data as "already normalized" here, because we don't want other normalization procedures to
69-
// potentially truncate the data we just already normalized, with a certain depth setting.
70-
addNonEnumerableProperty(normalizedErrorData, '__sentry_skip_normalization__', true);
71-
contexts[exceptionName] = normalizedErrorData;
72-
}
71+
const normalizedErrorData = normalize(errorData, depth);
7372

74-
return {
75-
...event,
76-
contexts,
77-
};
73+
if (isPlainObject(normalizedErrorData)) {
74+
// We mark the error data as "already normalized" here, because we don't want other normalization procedures to
75+
// potentially truncate the data we just already normalized, with a certain depth setting.
76+
addNonEnumerableProperty(normalizedErrorData, '__sentry_skip_normalization__', true);
77+
contexts[exceptionName] = normalizedErrorData;
7878
}
7979

80-
return event;
80+
return {
81+
...event,
82+
contexts,
83+
};
8184
}
8285

83-
/**
84-
* Extract extra information from the Error object
85-
*/
86-
private _extractErrorData(error: ExtendedError): Record<string, unknown> | null {
87-
// We are trying to enhance already existing event, so no harm done if it won't succeed
88-
try {
89-
const nativeKeys = [
90-
'name',
91-
'message',
92-
'stack',
93-
'line',
94-
'column',
95-
'fileName',
96-
'lineNumber',
97-
'columnNumber',
98-
'toJSON',
99-
];
100-
101-
const extraErrorInfo: Record<string, unknown> = {};
102-
103-
// We want only enumerable properties, thus `getOwnPropertyNames` is redundant here, as we filter keys anyway.
104-
for (const key of Object.keys(error)) {
105-
if (nativeKeys.indexOf(key) !== -1) {
106-
continue;
107-
}
108-
const value = error[key];
109-
extraErrorInfo[key] = isError(value) ? value.toString() : value;
86+
return event;
87+
}
88+
89+
/**
90+
* Extract extra information from the Error object
91+
*/
92+
function _extractErrorData(error: ExtendedError): Record<string, unknown> | null {
93+
// We are trying to enhance already existing event, so no harm done if it won't succeed
94+
try {
95+
const nativeKeys = [
96+
'name',
97+
'message',
98+
'stack',
99+
'line',
100+
'column',
101+
'fileName',
102+
'lineNumber',
103+
'columnNumber',
104+
'toJSON',
105+
];
106+
107+
const extraErrorInfo: Record<string, unknown> = {};
108+
109+
// We want only enumerable properties, thus `getOwnPropertyNames` is redundant here, as we filter keys anyway.
110+
for (const key of Object.keys(error)) {
111+
if (nativeKeys.indexOf(key) !== -1) {
112+
continue;
110113
}
114+
const value = error[key];
115+
extraErrorInfo[key] = isError(value) ? value.toString() : value;
116+
}
111117

112-
// Check if someone attached `toJSON` method to grab even more properties (eg. axios is doing that)
113-
if (typeof error.toJSON === 'function') {
114-
const serializedError = error.toJSON() as Record<string, unknown>;
118+
// Check if someone attached `toJSON` method to grab even more properties (eg. axios is doing that)
119+
if (typeof error.toJSON === 'function') {
120+
const serializedError = error.toJSON() as Record<string, unknown>;
115121

116-
for (const key of Object.keys(serializedError)) {
117-
const value = serializedError[key];
118-
extraErrorInfo[key] = isError(value) ? value.toString() : value;
119-
}
122+
for (const key of Object.keys(serializedError)) {
123+
const value = serializedError[key];
124+
extraErrorInfo[key] = isError(value) ? value.toString() : value;
120125
}
121-
122-
return extraErrorInfo;
123-
} catch (oO) {
124-
__DEBUG_BUILD__ && logger.error('Unable to extract extra data from the Error object:', oO);
125126
}
126127

127-
return null;
128+
return extraErrorInfo;
129+
} catch (oO) {
130+
__DEBUG_BUILD__ && logger.error('Unable to extract extra data from the Error object:', oO);
128131
}
132+
133+
return null;
129134
}

packages/integrations/src/rewriteframes.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Event, EventProcessor, Hub, Integration, StackFrame, Stacktrace } from '@sentry/types';
1+
import type { Event, Integration, StackFrame, Stacktrace } from '@sentry/types';
22
import { basename, relative } from '@sentry/utils';
33

44
type StackFrameIteratee = (frame: StackFrame) => StackFrame;
@@ -43,17 +43,18 @@ export class RewriteFrames implements Integration {
4343
/**
4444
* @inheritDoc
4545
*/
46-
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
47-
addGlobalEventProcessor(event => {
48-
const self = getCurrentHub().getIntegration(RewriteFrames);
49-
if (self) {
50-
return self.process(event);
51-
}
52-
return event;
53-
});
46+
public setupOnce(_addGlobaleventProcessor: unknown, _getCurrentHub: unknown): void {
47+
// noop
5448
}
5549

56-
/** JSDoc */
50+
/** @inheritDoc */
51+
public processEvent(event: Event): Event {
52+
return this.process(event);
53+
}
54+
55+
/**
56+
* TODO (v8): Make this private/internal
57+
*/
5758
public process(originalEvent: Event): Event {
5859
let processedEvent = originalEvent;
5960

packages/integrations/src/sessiontiming.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Event, EventProcessor, Hub, Integration } from '@sentry/types';
1+
import type { Event, Integration } from '@sentry/types';
22

33
/** This function adds duration since Sentry was initialized till the time event was sent */
44
export class SessionTiming implements Integration {
@@ -23,18 +23,17 @@ export class SessionTiming implements Integration {
2323
/**
2424
* @inheritDoc
2525
*/
26-
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
27-
addGlobalEventProcessor(event => {
28-
const self = getCurrentHub().getIntegration(SessionTiming);
29-
if (self) {
30-
return self.process(event);
31-
}
32-
return event;
33-
});
26+
public setupOnce(_addGlobaleventProcessor: unknown, _getCurrentHub: unknown): void {
27+
// noop
28+
}
29+
30+
/** @inheritDoc */
31+
public processEvent(event: Event): Event {
32+
return this.process(event);
3433
}
3534

3635
/**
37-
* @inheritDoc
36+
* TODO (v8): make this private/internal
3837
*/
3938
public process(event: Event): Event {
4039
const now = Date.now();

0 commit comments

Comments
 (0)