-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathclient.ts
145 lines (127 loc) · 4.28 KB
/
client.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import type { Scope } from '@sentry/core';
import { applySdkMetadata } from '@sentry/core';
import { BaseClient } from '@sentry/core';
import type {
BrowserClientProfilingOptions,
BrowserClientReplayOptions,
ClientOptions,
Event,
EventHint,
Options,
ParameterizedString,
SeverityLevel,
UserFeedback,
} from '@sentry/types';
import { createClientReportEnvelope, dsnToString, getSDKSource, logger } from '@sentry/utils';
import { DEBUG_BUILD } from './debug-build';
import { eventFromException, eventFromMessage } from './eventbuilder';
import { WINDOW } from './helpers';
import type { BrowserTransportOptions } from './transports/types';
import { createUserFeedbackEnvelope } from './userfeedback';
/**
* Configuration options for the Sentry Browser SDK.
* @see @sentry/types Options for more information.
*/
export type BrowserOptions = Options<BrowserTransportOptions> &
BrowserClientReplayOptions &
BrowserClientProfilingOptions;
/**
* Configuration options for the Sentry Browser SDK Client class
* @see BrowserClient for more information.
*/
export type BrowserClientOptions = ClientOptions<BrowserTransportOptions> &
BrowserClientReplayOptions &
BrowserClientProfilingOptions & {
/** If configured, this URL will be used as base URL for lazy loading integration. */
cdnBaseUrl?: string;
};
/**
* The Sentry Browser SDK Client.
*
* @see BrowserOptions for documentation on configuration options.
* @see SentryClient for usage documentation.
*/
export class BrowserClient extends BaseClient<BrowserClientOptions> {
/**
* Creates a new Browser SDK instance.
*
* @param options Configuration options for this SDK.
*/
public constructor(options: BrowserClientOptions) {
const opts = {
// We default this to true, as it is the safer scenario
parentSpanIsAlwaysRootSpan: true,
...options,
};
const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();
applySdkMetadata(opts, 'browser', ['browser'], sdkSource);
super(opts);
if (opts.sendClientReports && WINDOW.document) {
WINDOW.document.addEventListener('visibilitychange', () => {
if (WINDOW.document.visibilityState === 'hidden') {
this._flushOutcomes();
}
});
}
}
/**
* @inheritDoc
*/
public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {
return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);
}
/**
* @inheritDoc
*/
public eventFromMessage(
message: ParameterizedString,
level: SeverityLevel = 'info',
hint?: EventHint,
): PromiseLike<Event> {
return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);
}
/**
* Sends user feedback to Sentry.
*/
public captureUserFeedback(feedback: UserFeedback): void {
if (!this._isEnabled()) {
DEBUG_BUILD && logger.warn('SDK not enabled, will not capture user feedback.');
return;
}
const envelope = createUserFeedbackEnvelope(feedback, {
metadata: this.getSdkMetadata(),
dsn: this.getDsn(),
tunnel: this.getOptions().tunnel,
});
// sendEnvelope should not throw
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.sendEnvelope(envelope);
}
/**
* @inheritDoc
*/
protected _prepareEvent(event: Event, hint: EventHint, scope?: Scope): PromiseLike<Event | null> {
event.platform = event.platform || 'javascript';
return super._prepareEvent(event, hint, scope);
}
/**
* Sends client reports as an envelope.
*/
private _flushOutcomes(): void {
const outcomes = this._clearOutcomes();
if (outcomes.length === 0) {
DEBUG_BUILD && logger.log('No outcomes to send');
return;
}
// This is really the only place where we want to check for a DSN and only send outcomes then
if (!this._dsn) {
DEBUG_BUILD && logger.log('No dsn provided, will not send outcomes');
return;
}
DEBUG_BUILD && logger.log('Sending outcomes:', outcomes);
const envelope = createClientReportEnvelope(outcomes, this._options.tunnel && dsnToString(this._dsn));
// sendEnvelope should not throw
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.sendEnvelope(envelope);
}
}