UNPKG

4.34 kBJavaScriptView Raw
1import { BaseClient, SDK_VERSION } from '@sentry/core';
2import { getSDKSource, logger, createClientReportEnvelope, dsnToString } from '@sentry/utils';
3import { eventFromException, eventFromMessage } from './eventbuilder.js';
4import { WINDOW } from './helpers.js';
5import { BREADCRUMB_INTEGRATION_ID } from './integrations/breadcrumbs.js';
6import { createUserFeedbackEnvelope } from './userfeedback.js';
7
8/**
9 * Configuration options for the Sentry Browser SDK.
10 * @see @sentry/types Options for more information.
11 */
12
13/**
14 * The Sentry Browser SDK Client.
15 *
16 * @see BrowserOptions for documentation on configuration options.
17 * @see SentryClient for usage documentation.
18 */
19class BrowserClient extends BaseClient {
20 /**
21 * Creates a new Browser SDK instance.
22 *
23 * @param options Configuration options for this SDK.
24 */
25 constructor(options) {
26 const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();
27
28 options._metadata = options._metadata || {};
29 options._metadata.sdk = options._metadata.sdk || {
30 name: 'sentry.javascript.browser',
31 packages: [
32 {
33 name: `${sdkSource}:@sentry/browser`,
34 version: SDK_VERSION,
35 },
36 ],
37 version: SDK_VERSION,
38 };
39
40 super(options);
41
42 if (options.sendClientReports && WINDOW.document) {
43 WINDOW.document.addEventListener('visibilitychange', () => {
44 if (WINDOW.document.visibilityState === 'hidden') {
45 this._flushOutcomes();
46 }
47 });
48 }
49 }
50
51 /**
52 * @inheritDoc
53 */
54 eventFromException(exception, hint) {
55 return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);
56 }
57
58 /**
59 * @inheritDoc
60 */
61 eventFromMessage(
62 message,
63 // eslint-disable-next-line deprecation/deprecation
64 level = 'info',
65 hint,
66 ) {
67 return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);
68 }
69
70 /**
71 * @inheritDoc
72 */
73 sendEvent(event, hint) {
74 // We only want to add the sentry event breadcrumb when the user has the breadcrumb integration installed and
75 // activated its `sentry` option.
76 // We also do not want to use the `Breadcrumbs` class here directly, because we do not want it to be included in
77 // bundles, if it is not used by the SDK.
78 // This all sadly is a bit ugly, but we currently don't have a "pre-send" hook on the integrations so we do it this
79 // way for now.
80 const breadcrumbIntegration = this.getIntegrationById(BREADCRUMB_INTEGRATION_ID) ;
81 // We check for definedness of `addSentryBreadcrumb` in case users provided their own integration with id
82 // "Breadcrumbs" that does not have this function.
83 if (breadcrumbIntegration && breadcrumbIntegration.addSentryBreadcrumb) {
84 breadcrumbIntegration.addSentryBreadcrumb(event);
85 }
86
87 super.sendEvent(event, hint);
88 }
89
90 /**
91 * Sends user feedback to Sentry.
92 */
93 captureUserFeedback(feedback) {
94 if (!this._isEnabled()) {
95 (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('SDK not enabled, will not capture user feedback.');
96 return;
97 }
98
99 const envelope = createUserFeedbackEnvelope(feedback, {
100 metadata: this.getSdkMetadata(),
101 dsn: this.getDsn(),
102 tunnel: this.getOptions().tunnel,
103 });
104 void this._sendEnvelope(envelope);
105 }
106
107 /**
108 * @inheritDoc
109 */
110 _prepareEvent(event, hint, scope) {
111 event.platform = event.platform || 'javascript';
112 return super._prepareEvent(event, hint, scope);
113 }
114
115 /**
116 * Sends client reports as an envelope.
117 */
118 _flushOutcomes() {
119 const outcomes = this._clearOutcomes();
120
121 if (outcomes.length === 0) {
122 (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('No outcomes to send');
123 return;
124 }
125
126 if (!this._dsn) {
127 (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('No dsn provided, will not send outcomes');
128 return;
129 }
130
131 (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('Sending outcomes:', outcomes);
132
133 const envelope = createClientReportEnvelope(outcomes, this._options.tunnel && dsnToString(this._dsn));
134 void this._sendEnvelope(envelope);
135 }
136}
137
138export { BrowserClient };
139//# sourceMappingURL=client.js.map