Skip to content

Commit 3bfb1d2

Browse files
committed
[v7] Unify BrowserClient/NodeClient and extract majority of functionalities to BaseClient
1 parent 1d007e7 commit 3bfb1d2

File tree

10 files changed

+176
-265
lines changed

10 files changed

+176
-265
lines changed

packages/browser/src/client.ts

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import { BaseClient, Scope, SDK_VERSION } from '@sentry/core';
1+
import { BaseClient, SDK_VERSION } from '@sentry/core';
22
import { Event, EventHint, Options, Severity } from '@sentry/types';
33
import { getGlobalObject, logger, supportsFetch } from '@sentry/utils';
4-
import { NoopTransport, ReportDialogOptions, Transport, TransportOptions } from '@sentry/transport-base';
4+
import { ReportDialogOptions } from '@sentry/transport-base';
55
import { FetchTransport } from '@sentry/transport-fetch';
66
import { XHRTransport } from '@sentry/transport-xhr';
77

88
import { injectReportDialog } from './helpers';
9-
import { Breadcrumbs } from './integrations';
109
import { eventFromException, eventFromMessage } from './eventbuilder';
1110

1211
/**
@@ -28,12 +27,6 @@ export interface BrowserOptions extends Options {
2827
*/
2928
denyUrls?: Array<string | RegExp>;
3029

31-
/** @deprecated use {@link Options.allowUrls} instead. */
32-
whitelistUrls?: Array<string | RegExp>;
33-
34-
/** @deprecated use {@link Options.denyUrls} instead. */
35-
blacklistUrls?: Array<string | RegExp>;
36-
3730
/**
3831
* A flag enabling Sessions Tracking feature.
3932
* By default Sessions Tracking is disabled.
@@ -65,23 +58,11 @@ export class BrowserClient extends BaseClient<BrowserOptions> {
6558
],
6659
version: SDK_VERSION,
6760
};
61+
options.transport = options.transport ?? (supportsFetch() ? FetchTransport : XHRTransport);
6862

6963
super(options);
7064
}
7165

72-
/**
73-
* @inheritDoc
74-
*/
75-
public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {
76-
return eventFromException(this._options, exception, hint);
77-
}
78-
/**
79-
* @inheritDoc
80-
*/
81-
public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike<Event> {
82-
return eventFromMessage(this._options, message, level, hint);
83-
}
84-
8566
/**
8667
* Show a report dialog to the user to send feedback to a specific event.
8768
*
@@ -108,41 +89,22 @@ export class BrowserClient extends BaseClient<BrowserOptions> {
10889
/**
10990
* @inheritDoc
11091
*/
111-
protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): PromiseLike<Event | null> {
112-
event.platform = event.platform || 'javascript';
113-
return super._prepareEvent(event, scope, hint);
92+
protected _eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {
93+
return eventFromException(this._options, exception, hint);
11494
}
115-
11695
/**
11796
* @inheritDoc
11897
*/
119-
protected _sendEvent(event: Event): void {
120-
const integration = this.getIntegration(Breadcrumbs);
121-
if (integration) {
122-
integration.addSentryBreadcrumb(event);
123-
}
124-
super._sendEvent(event);
98+
protected _eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike<Event> {
99+
return eventFromMessage(this._options, message, level, hint);
125100
}
126101

127-
protected _setupTransport(): Transport {
128-
// TODO: This whole function should be unnecessary and moved to client construction
129-
if (!this._options.dsn) {
130-
// We return the noop transport here in case there is no Dsn.
131-
return new NoopTransport();
132-
}
133-
134-
const transportOptions: TransportOptions = {
135-
...this._options.transportOptions,
136-
dsn: this._options.transportOptions?.dsn ?? this._options.dsn,
137-
};
138-
139-
if (this._options.transport) {
140-
return new this._options.transport(transportOptions);
141-
}
142-
143-
if (supportsFetch()) {
144-
return new FetchTransport(transportOptions);
145-
}
146-
return new XHRTransport(transportOptions);
147-
}
102+
// TODO: Restore this functionality somewhere else, it definitely shouldn't be here.
103+
// protected _sendEvent(event: Event): void {
104+
// const integration = this.getIntegration(Breadcrumbs);
105+
// if (integration) {
106+
// integration.addSentryBreadcrumb(event);
107+
// }
108+
// super._sendEvent(event);
109+
// }
148110
}

packages/browser/src/eventbuilder.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Event, EventHint, Options, Severity } from '@sentry/types';
1+
import { Event, EventHint, Severity } from '@sentry/types';
22
import {
33
addExceptionMechanism,
44
addExceptionTypeValue,
@@ -11,14 +11,15 @@ import {
1111
SyncPromise,
1212
} from '@sentry/utils';
1313

14+
import { BrowserOptions } from './client';
1415
import { eventFromPlainObject, eventFromStacktrace, prepareFramesForEvent } from './parsers';
1516
import { computeStackTrace } from './tracekit';
1617

1718
/**
1819
* Builds and Event from a Exception
1920
* @hidden
2021
*/
21-
export function eventFromException(options: Options, exception: unknown, hint?: EventHint): PromiseLike<Event> {
22+
export function eventFromException(options: BrowserOptions, exception: unknown, hint?: EventHint): PromiseLike<Event> {
2223
const syntheticException = (hint && hint.syntheticException) || undefined;
2324
const event = eventFromUnknownInput(exception, syntheticException, {
2425
attachStacktrace: options.attachStacktrace,
@@ -27,10 +28,11 @@ export function eventFromException(options: Options, exception: unknown, hint?:
2728
handled: true,
2829
type: 'generic',
2930
});
30-
event.level = Severity.Error;
3131
if (hint && hint.event_id) {
3232
event.event_id = hint.event_id;
3333
}
34+
event.level = Severity.Error;
35+
event.platform = 'javascript';
3436
return SyncPromise.resolve(event);
3537
}
3638

@@ -39,7 +41,7 @@ export function eventFromException(options: Options, exception: unknown, hint?:
3941
* @hidden
4042
*/
4143
export function eventFromMessage(
42-
options: Options,
44+
options: BrowserOptions,
4345
message: string,
4446
level: Severity = Severity.Info,
4547
hint?: EventHint,
@@ -48,10 +50,11 @@ export function eventFromMessage(
4850
const event = eventFromString(message, syntheticException, {
4951
attachStacktrace: options.attachStacktrace,
5052
});
51-
event.level = level;
5253
if (hint && hint.event_id) {
5354
event.event_id = hint.event_id;
5455
}
56+
event.level = level;
57+
event.platform = 'javascript';
5558
return SyncPromise.resolve(event);
5659
}
5760

packages/browser/src/exports.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export {
3939
} from '@sentry/core';
4040

4141
export { BrowserClient, BrowserOptions } from './client';
42-
export { injectReportDialog } from './helpers';
4342
export { eventFromException, eventFromMessage } from './eventbuilder';
4443
export { defaultIntegrations, forceLoad, init, lastEventId, onLoad, showReportDialog, flush, close, wrap } from './sdk';
4544
export { SDK_NAME } from './version';

packages/core/src/baseclient.ts

Lines changed: 43 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -95,28 +95,6 @@ export interface ClientLike<O extends Options = Options> {
9595

9696
/** Returns an array of installed integrations on the client. */
9797
getIntegration<T extends Integration>(integration: IntegrationClass<T>): T | null;
98-
99-
/** This is an internal function to setup all integrations that should run on the client */
100-
setupIntegrations(): void;
101-
102-
// TODO: Anything below has been moved from backend to make it compile only. Rework.
103-
104-
/** Creates a {@link Event} from an exception. */
105-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
106-
eventFromException(exception: any, hint?: EventHint): PromiseLike<Event>;
107-
108-
/** Creates a {@link Event} from a plain message. */
109-
eventFromMessage(message: string, level?: Severity, hint?: EventHint): PromiseLike<Event>;
110-
111-
sendRequest<T>(request: TransportRequest<T>): void;
112-
113-
/**
114-
* Returns the transport that is used by the backend.
115-
* Please note that the transport gets lazy initialized so it will only be there once the first event has been sent.
116-
*
117-
* @returns The transport.
118-
*/
119-
getTransport(): Transport;
12098
}
12199

122100
/**
@@ -181,31 +159,6 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
181159
this._transport = this._setupTransport();
182160
}
183161

184-
public eventFromException(_exception: any, _hint?: EventHint): PromiseLike<Event> {
185-
return Promise.resolve({});
186-
}
187-
188-
public eventFromMessage(_message: string, _level: Severity = Severity.Info, _hint?: EventHint): PromiseLike<Event> {
189-
return Promise.resolve({});
190-
}
191-
192-
/**
193-
* @inheritDoc
194-
*/
195-
// TODO: Do we need generic here?
196-
public sendRequest<T>(request: TransportRequest<T>): void {
197-
this._transport.sendRequest(request).then(null, reason => {
198-
logger.error(`Failed sending request: ${reason}`);
199-
});
200-
}
201-
202-
/**
203-
* @inheritDoc
204-
*/
205-
public getTransport(): Transport {
206-
return this._transport;
207-
}
208-
209162
/**
210163
* @inheritDoc
211164
*/
@@ -214,7 +167,7 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
214167
let eventId: string | undefined = hint && hint.event_id;
215168

216169
this._process(
217-
this.eventFromException(exception, hint)
170+
this._eventFromException(exception, hint)
218171
.then(event => this._captureEvent(event, hint, scope))
219172
.then(result => {
220173
eventId = result;
@@ -227,12 +180,17 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
227180
/**
228181
* @inheritDoc
229182
*/
230-
public captureMessage(message: string, level?: Severity, hint?: EventHint, scope?: Scope): string | undefined {
183+
public captureMessage(
184+
message: string,
185+
level: Severity = Severity.Info,
186+
hint?: EventHint,
187+
scope?: Scope,
188+
): string | undefined {
231189
let eventId: string | undefined = hint && hint.event_id;
232190

233191
const promisedEvent = isPrimitive(message)
234-
? this.eventFromMessage(String(message), level, hint)
235-
: this.eventFromException(message, hint);
192+
? this._eventFromMessage(String(message), level, hint)
193+
: this._eventFromException(message, hint);
236194

237195
this._process(
238196
promisedEvent
@@ -292,9 +250,7 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
292250
*/
293251
public flush(timeout?: number): PromiseLike<boolean> {
294252
return this._isClientProcessing(timeout).then(ready => {
295-
return this.getTransport()
296-
.flush(timeout ?? 0)
297-
.then(transportFlushed => ready && transportFlushed);
253+
return this._transport.flush(timeout ?? 0).then(transportFlushed => ready && transportFlushed);
298254
});
299255
}
300256

@@ -308,15 +264,6 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
308264
});
309265
}
310266

311-
/**
312-
* Sets up the integrations
313-
*/
314-
public setupIntegrations(): void {
315-
if (this._isEnabled()) {
316-
this._integrations = setupIntegrations(this._options);
317-
}
318-
}
319-
320267
/**
321268
* @inheritDoc
322269
*/
@@ -329,9 +276,38 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
329276
}
330277
}
331278

279+
/**
280+
* Sets up the integrations
281+
*/
282+
protected _setupIntegrations(): void {
283+
if (this._isEnabled()) {
284+
this._integrations = setupIntegrations(this._options);
285+
}
286+
}
287+
332288
protected _setupTransport(): Transport {
333-
// We return the noop transport here in case there is no Dsn.
334-
return new NoopTransport();
289+
// TODO: This whole function should be unnecessary and moved to client construction
290+
if (!this._options.dsn || !this._options.transport) {
291+
return new NoopTransport();
292+
}
293+
294+
return new this._options.transport({
295+
dsn: this._options.dsn,
296+
...this._options.transportOptions,
297+
// TODO: Deprecate these options and move to `transportOptions`
298+
// ...(this._options.httpProxy && { httpProxy: this._options.httpProxy }),
299+
// ...(this._options.httpsProxy && { httpsProxy: this._options.httpsProxy }),
300+
// ...(this._options.caCerts && { caCerts: this._options.caCerts }),
301+
});
302+
}
303+
/**
304+
* @inheritDoc
305+
*/
306+
// TODO: Do we need generic here?
307+
protected _sendRequest<T>(request: TransportRequest<T>): void {
308+
this._transport.sendRequest(request).then(null, reason => {
309+
logger.error(`Failed sending request: ${reason}`);
310+
});
335311
}
336312

337313
/** Updates existing session based on the provided event */
@@ -375,7 +351,7 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
375351

376352
/** Deliver captured session to Sentry */
377353
protected _sendSession(session: Session): void {
378-
this.sendRequest(sessionToTransportRequest(session));
354+
this._sendRequest(sessionToTransportRequest(session));
379355
}
380356

381357
/** Waits for the client to be done with processing. */
@@ -557,7 +533,7 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
557533
* @param event The Sentry event to send
558534
*/
559535
protected _sendEvent(event: Event): void {
560-
this.sendRequest(eventToTransportRequest(event));
536+
this._sendRequest(eventToTransportRequest(event));
561537
}
562538

563539
/**

packages/core/src/integrations/inboundfilters.ts

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ interface InboundFiltersOptions {
1111
denyUrls: Array<string | RegExp>;
1212
ignoreErrors: Array<string | RegExp>;
1313
ignoreInternal: boolean;
14-
15-
/** @deprecated use {@link InboundFiltersOptions.allowUrls} instead. */
16-
whitelistUrls: Array<string | RegExp>;
17-
/** @deprecated use {@link InboundFiltersOptions.denyUrls} instead. */
18-
blacklistUrls: Array<string | RegExp>;
1914
}
2015

2116
/** Inbound filters configurable by the user */
@@ -134,22 +129,8 @@ export class InboundFilters implements Integration {
134129

135130
private _mergeOptions(clientOptions: Partial<InboundFiltersOptions> = {}): Partial<InboundFiltersOptions> {
136131
return {
137-
allowUrls: [
138-
// eslint-disable-next-line deprecation/deprecation
139-
...(this._options.whitelistUrls || []),
140-
...(this._options.allowUrls || []),
141-
// eslint-disable-next-line deprecation/deprecation
142-
...(clientOptions.whitelistUrls || []),
143-
...(clientOptions.allowUrls || []),
144-
],
145-
denyUrls: [
146-
// eslint-disable-next-line deprecation/deprecation
147-
...(this._options.blacklistUrls || []),
148-
...(this._options.denyUrls || []),
149-
// eslint-disable-next-line deprecation/deprecation
150-
...(clientOptions.blacklistUrls || []),
151-
...(clientOptions.denyUrls || []),
152-
],
132+
allowUrls: [...(this._options.allowUrls || []), ...(clientOptions.allowUrls || [])],
133+
denyUrls: [...(this._options.denyUrls || []), ...(clientOptions.denyUrls || [])],
153134
ignoreErrors: [
154135
...(this._options.ignoreErrors || []),
155136
...(clientOptions.ignoreErrors || []),

packages/hub/src/hub.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ export class Hub implements HubInterface {
8585
public bindClient(client?: Client): void {
8686
const top = this.getStackTop();
8787
top.client = client;
88+
// @ts-ignore TODO: integrations wont be instantiated by the hub anymore, left here so we compile
8889
if (client && client.setupIntegrations) {
90+
// @ts-ignore TODO: integrations wont be instantiated by the hub anymore, left here so we compile
8991
client.setupIntegrations();
9092
}
9193
}

0 commit comments

Comments
 (0)