Skip to content

Commit 201cc49

Browse files
HazATkamilogorek
authored andcommitted
feat: Use SyncPromise internally, remove deprecated and some public APIs (#1858)
* ref: Move PromiseBuffer and Error to utils package * ref: Remove all async api * ref: Remove invokeClientAsync function * feat: Finish Node SDK * feat: SyncPromise implementation * fix: Browser SDK * fix: beforeSend callback * fix: Core tests * fix: linting and tests * fix: browser npm package + add error for manual tests * meta: Remove deprecations * fix: Typedocs and public exposed functions * meta: Changelog * Apply suggestions from code review
1 parent 1c70060 commit 201cc49

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1418
-776
lines changed

packages/browser/rollup.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export default [
6666
interop: false,
6767
sourcemap: true,
6868
},
69-
external: ['@sentry/core', '@sentry/hub', '@sentry/minimal', 'tslib'],
69+
external: ['@sentry/core', '@sentry/hub', '@sentry/minimal'],
7070
plugins: [
7171
typescript({
7272
tsconfig: 'tsconfig.build.json',

packages/browser/src/backend.ts

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { BaseBackend, Options, SentryError } from '@sentry/core';
1+
import { BaseBackend, Options } from '@sentry/core';
22
import { SentryEvent, SentryEventHint, Severity, Transport } from '@sentry/types';
3+
import { SentryError } from '@sentry/utils/error';
34
import { isDOMError, isDOMException, isError, isErrorEvent, isPlainObject } from '@sentry/utils/is';
45
import { supportsBeacon, supportsFetch } from '@sentry/utils/supports';
6+
import { SyncPromise } from '@sentry/utils/syncpromise';
57
import { addExceptionTypeValue, eventFromPlainObject, eventFromStacktrace, prepareFramesForEvent } from './parsers';
68
import { computeStackTrace } from './tracekit';
79
import { BeaconTransport, FetchTransport, XHRTransport } from './transports';
@@ -26,7 +28,10 @@ export interface BrowserOptions extends Options {
2628
whitelistUrls?: Array<string | RegExp>;
2729
}
2830

29-
/** The Sentry Browser SDK Backend. */
31+
/**
32+
* The Sentry Browser SDK Backend.
33+
* @hidden
34+
*/
3035
export class BrowserBackend extends BaseBackend<BrowserOptions> {
3136
/**
3237
* @inheritDoc
@@ -69,48 +74,60 @@ export class BrowserBackend extends BaseBackend<BrowserOptions> {
6974
/**
7075
* @inheritDoc
7176
*/
72-
public async eventFromException(exception: any, hint?: SentryEventHint): Promise<SentryEvent> {
73-
let event;
77+
public eventFromException(exception: any, hint?: SentryEventHint): SyncPromise<SentryEvent> {
78+
let event: SentryEvent;
7479

7580
if (isErrorEvent(exception as ErrorEvent) && (exception as ErrorEvent).error) {
7681
// If it is an ErrorEvent with `error` property, extract it to get actual Error
77-
const ex = exception as ErrorEvent;
78-
exception = ex.error; // tslint:disable-line:no-parameter-reassignment
82+
const errorEvent = exception as ErrorEvent;
83+
exception = errorEvent.error; // tslint:disable-line:no-parameter-reassignment
7984
event = eventFromStacktrace(computeStackTrace(exception as Error));
85+
return SyncPromise.resolve(this.buildEvent(event));
8086
} else if (isDOMError(exception as DOMError) || isDOMException(exception as DOMException)) {
8187
// If it is a DOMError or DOMException (which are legacy APIs, but still supported in some browsers)
8288
// then we just extract the name and message, as they don't provide anything else
8389
// https://developer.mozilla.org/en-US/docs/Web/API/DOMError
8490
// https://developer.mozilla.org/en-US/docs/Web/API/DOMException
85-
const ex = exception as DOMException;
86-
const name = ex.name || (isDOMError(ex) ? 'DOMError' : 'DOMException');
87-
const message = ex.message ? `${name}: ${ex.message}` : name;
88-
89-
event = await this.eventFromMessage(message, Severity.Error, hint);
90-
addExceptionTypeValue(event, message);
91+
const domException = exception as DOMException;
92+
const name = domException.name || (isDOMError(domException) ? 'DOMError' : 'DOMException');
93+
const message = domException.message ? `${name}: ${domException.message}` : name;
94+
95+
return this.eventFromMessage(message, Severity.Error, hint).then(messageEvent => {
96+
addExceptionTypeValue(messageEvent, message);
97+
return SyncPromise.resolve(this.buildEvent(messageEvent));
98+
});
9199
} else if (isError(exception as Error)) {
92100
// we have a real Error object, do nothing
93101
event = eventFromStacktrace(computeStackTrace(exception as Error));
102+
return SyncPromise.resolve(this.buildEvent(event));
94103
} else if (isPlainObject(exception as {}) && hint && hint.syntheticException) {
95104
// If it is plain Object, serialize it manually and extract options
96105
// This will allow us to group events based on top-level keys
97106
// which is much better than creating new group when any key/value change
98-
const ex = exception as {};
99-
event = eventFromPlainObject(ex, hint.syntheticException);
107+
const objectException = exception as {};
108+
event = eventFromPlainObject(objectException, hint.syntheticException);
100109
addExceptionTypeValue(event, 'Custom Object');
101-
} else {
102-
// If none of previous checks were valid, then it means that
103-
// it's not a DOMError/DOMException
104-
// it's not a plain Object
105-
// it's not a valid ErrorEvent (one with an error property)
106-
// it's not an Error
107-
// So bail out and capture it as a simple message:
108-
const ex = exception as string;
109-
event = await this.eventFromMessage(ex, undefined, hint);
110-
addExceptionTypeValue(event, `${ex}`);
110+
return SyncPromise.resolve(this.buildEvent(event));
111111
}
112112

113-
event = {
113+
// If none of previous checks were valid, then it means that
114+
// it's not a DOMError/DOMException
115+
// it's not a plain Object
116+
// it's not a valid ErrorEvent (one with an error property)
117+
// it's not an Error
118+
// So bail out and capture it as a simple message:
119+
const stringException = exception as string;
120+
return this.eventFromMessage(stringException, undefined, hint).then(messageEvent => {
121+
addExceptionTypeValue(messageEvent, `${stringException}`);
122+
return SyncPromise.resolve(this.buildEvent(messageEvent));
123+
});
124+
}
125+
126+
/**
127+
* This is an internal helper function that creates an event.
128+
*/
129+
private buildEvent(event: SentryEvent, hint?: SentryEventHint): SentryEvent {
130+
return {
114131
...event,
115132
event_id: hint && hint.event_id,
116133
exception: {
@@ -121,18 +138,16 @@ export class BrowserBackend extends BaseBackend<BrowserOptions> {
121138
},
122139
},
123140
};
124-
125-
return event;
126141
}
127142

128143
/**
129144
* @inheritDoc
130145
*/
131-
public async eventFromMessage(
146+
public eventFromMessage(
132147
message: string,
133148
level: Severity = Severity.Info,
134149
hint?: SentryEventHint,
135-
): Promise<SentryEvent> {
150+
): SyncPromise<SentryEvent> {
136151
const event: SentryEvent = {
137152
event_id: hint && hint.event_id,
138153
level,
@@ -147,6 +162,6 @@ export class BrowserBackend extends BaseBackend<BrowserOptions> {
147162
};
148163
}
149164

150-
return event;
165+
return SyncPromise.resolve(event);
151166
}
152167
}

packages/browser/src/client.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { API, BaseClient, Scope } from '@sentry/core';
22
import { DsnLike, SentryEvent, SentryEventHint } from '@sentry/types';
33
import { logger } from '@sentry/utils/logger';
44
import { getGlobalObject } from '@sentry/utils/misc';
5+
import { SyncPromise } from '@sentry/utils/syncpromise';
56
import { BrowserBackend, BrowserOptions } from './backend';
67
import { SDK_NAME, SDK_VERSION } from './version';
78

@@ -49,7 +50,7 @@ export class BrowserClient extends BaseClient<BrowserBackend, BrowserOptions> {
4950
/**
5051
* @inheritDoc
5152
*/
52-
protected async prepareEvent(event: SentryEvent, scope?: Scope, hint?: SentryEventHint): Promise<SentryEvent | null> {
53+
protected prepareEvent(event: SentryEvent, scope?: Scope, hint?: SentryEventHint): SyncPromise<SentryEvent | null> {
5354
event.platform = event.platform || 'javascript';
5455
event.sdk = {
5556
...event.sdk,

packages/browser/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export {
2727
Scope,
2828
} from '@sentry/core';
2929

30-
export { BrowserBackend, BrowserOptions } from './backend';
30+
export { BrowserOptions } from './backend';
3131
export { BrowserClient, ReportDialogOptions } from './client';
3232
export { defaultIntegrations, forceLoad, init, lastEventId, onLoad, showReportDialog, flush, close } from './sdk';
3333
export { SDK_NAME, SDK_VERSION } from './version';

packages/browser/src/integrations/breadcrumbs.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import { breadcrumbEventHandler, keypressEventHandler, wrap } from './helpers';
1212
const global = getGlobalObject() as Window;
1313
let lastHref: string | undefined;
1414

15-
/** JSDoc */
15+
/**
16+
* @hidden
17+
*/
1618
export interface SentryWrappedXMLHttpRequest extends XMLHttpRequest {
1719
[key: string]: any;
1820
__sentry_xhr__?: {

packages/browser/src/integrations/helpers.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@ let keypressTimeout: number | undefined;
99
let lastCapturedEvent: Event | undefined;
1010
let ignoreOnError: number = 0;
1111

12-
/** JSDoc */
12+
/**
13+
* @hidden
14+
*/
1315
export function shouldIgnoreOnError(): boolean {
1416
return ignoreOnError > 0;
1517
}
16-
/** JSDoc */
18+
19+
/**
20+
* @hidden
21+
*/
1722
export function ignoreNextOnError(): void {
1823
// onerror should trigger before setTimeout
1924
ignoreOnError += 1;
@@ -28,6 +33,7 @@ export function ignoreNextOnError(): void {
2833
*
2934
* @param fn A function to wrap.
3035
* @returns The wrapped function.
36+
* @hidden
3137
*/
3238
export function wrap(
3339
fn: SentryWrappedFunction,
@@ -79,8 +85,8 @@ export function wrap(
7985
} catch (ex) {
8086
ignoreNextOnError();
8187

82-
withScope(async scope => {
83-
scope.addEventProcessor(async (event: SentryEvent) => {
88+
withScope(scope => {
89+
scope.addEventProcessor((event: SentryEvent) => {
8490
const processedEvent = { ...event };
8591

8692
if (options.mechanism) {
@@ -152,6 +158,7 @@ export function wrap(
152158
* Wraps addEventListener to capture UI breadcrumbs
153159
* @param eventName the event name (e.g. "click")
154160
* @returns wrapped breadcrumb events handler
161+
* @hidden
155162
*/
156163
export function breadcrumbEventHandler(eventName: string): (event: Event) => void {
157164
return (event: Event) => {
@@ -196,6 +203,7 @@ export function breadcrumbEventHandler(eventName: string): (event: Event) => voi
196203
/**
197204
* Wraps addEventListener to capture keypress UI events
198205
* @returns wrapped keypress events handler
206+
* @hidden
199207
*/
200208
export function keypressEventHandler(): (event: Event) => void {
201209
// TODO: if somehow user switches keypress target before

packages/browser/src/integrations/linkederrors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class LinkedErrors implements Integration {
4747
* @inheritDoc
4848
*/
4949
public setupOnce(): void {
50-
addGlobalEventProcessor(async (event: SentryEvent, hint?: SentryEventHint) => {
50+
addGlobalEventProcessor((event: SentryEvent, hint?: SentryEventHint) => {
5151
const self = getCurrentHub().getIntegration(LinkedErrors);
5252
if (self) {
5353
return self.handler(event, hint);

packages/browser/src/integrations/pluggable/ember.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export class Ember implements Integration {
8181
* @param scope The scope currently used.
8282
*/
8383
private addIntegrationToSdkInfo(scope: Scope): void {
84-
scope.addEventProcessor(async (event: SentryEvent) => {
84+
scope.addEventProcessor((event: SentryEvent) => {
8585
if (event.sdk) {
8686
const integrations = event.sdk.integrations || [];
8787
event.sdk = {

packages/browser/src/integrations/pluggable/vue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class Vue implements Integration {
9292
scope.setExtra(key, metadata[key]);
9393
});
9494

95-
scope.addEventProcessor(async (event: SentryEvent) => {
95+
scope.addEventProcessor((event: SentryEvent) => {
9696
if (event.sdk) {
9797
const integrations = event.sdk.integrations || [];
9898
event.sdk = {

packages/browser/src/integrations/useragent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export class UserAgent implements Integration {
2020
* @inheritDoc
2121
*/
2222
public setupOnce(): void {
23-
addGlobalEventProcessor(async (event: SentryEvent) => {
23+
addGlobalEventProcessor((event: SentryEvent) => {
2424
if (getCurrentHub().getIntegration(UserAgent)) {
2525
if (!global.navigator || !global.location) {
2626
return event;

packages/browser/src/parsers.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const STACKTRACE_LIMIT = 50;
99
/**
1010
* This function creates an exception from an TraceKitStackTrace
1111
* @param stacktrace TraceKitStackTrace that will be converted to an exception
12+
* @hidden
1213
*/
1314
export function exceptionFromStacktrace(stacktrace: TraceKitStackTrace): SentryException {
1415
const frames = prepareFramesForEvent(stacktrace.stack);
@@ -30,7 +31,9 @@ export function exceptionFromStacktrace(stacktrace: TraceKitStackTrace): SentryE
3031
return exception;
3132
}
3233

33-
/** JSDoc */
34+
/**
35+
* @hidden
36+
*/
3437
export function eventFromPlainObject(exception: {}, syntheticException: Error | null): SentryEvent {
3538
const exceptionKeys = Object.keys(exception).sort();
3639
const event: SentryEvent = {
@@ -52,7 +55,9 @@ export function eventFromPlainObject(exception: {}, syntheticException: Error |
5255
return event;
5356
}
5457

55-
/** JSDoc */
58+
/**
59+
* @hidden
60+
*/
5661
export function eventFromStacktrace(stacktrace: TraceKitStackTrace): SentryEvent {
5762
const exception = exceptionFromStacktrace(stacktrace);
5863

@@ -63,7 +68,9 @@ export function eventFromStacktrace(stacktrace: TraceKitStackTrace): SentryEvent
6368
};
6469
}
6570

66-
/** JSDoc */
71+
/**
72+
* @hidden
73+
*/
6774
export function prepareFramesForEvent(stack: TraceKitStackFrame[]): StackFrame[] {
6875
if (!stack || !stack.length) {
6976
return [];
@@ -104,6 +111,7 @@ export function prepareFramesForEvent(stack: TraceKitStackFrame[]): StackFrame[]
104111
* @param event The event to modify.
105112
* @param value Value of the exception.
106113
* @param type Type of the exception.
114+
* @hidden
107115
*/
108116
export function addExceptionTypeValue(event: SentryEvent, value?: string, type?: string): void {
109117
event.exception = event.exception || {};

0 commit comments

Comments
 (0)