Skip to content

Commit 232b75b

Browse files
committed
Merge remote-tracking branch 'upstream/7.x' into feat/attachments
2 parents 6cc6d60 + 39553b5 commit 232b75b

File tree

5 files changed

+74
-59
lines changed

5 files changed

+74
-59
lines changed

packages/browser/src/client.ts

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, Scope, SDK_VERSION } from '@sentry/core';
2-
import { AttachmentWithData, ClientOptions, Event, EventHint, Options, Severity, SeverityLevel } from '@sentry/types';
3-
import { createClientReportEnvelope, dsnToString, getGlobalObject, logger, serializeEnvelope } from '@sentry/utils';
1+
import { BaseClient, getCurrentHub, getEnvelopeEndpointWithUrlEncodedAuth, Scope, SDK_VERSION } from '@sentry/core';
2+
import { AttachmentWithData,ClientOptions, Event, EventHint, Options, Severity, SeverityLevel } from '@sentry/types';
3+
import {
4+
createClientReportEnvelope,
5+
dsnToString,
6+
getEventDescription,
7+
getGlobalObject,
8+
logger,
9+
serializeEnvelope,
10+
} from '@sentry/utils';
411

512
import { eventFromException, eventFromMessage } from './eventbuilder';
613
import { IS_DEBUG_BUILD } from './flags';
714
import { Breadcrumbs } from './integrations';
15+
import { BREADCRUMB_INTEGRATION_ID } from './integrations/breadcrumbs';
816
import { sendReport } from './transports/utils';
917

1018
const globalObject = getGlobalObject<Window>();
@@ -95,20 +103,44 @@ export class BrowserClient extends BaseClient<BrowserClientOptions> {
95103
/**
96104
* @inheritDoc
97105
*/
98-
protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): PromiseLike<Event | null> {
99-
event.platform = event.platform || 'javascript';
100-
return super._prepareEvent(event, scope, hint);
106+
public sendEvent(event: Event, attachments?: AttachmentWithData[]): void {
107+
// We only want to add the sentry event breadcrumb when the user has the breadcrumb integration installed and
108+
// activated its `sentry` option.
109+
// We also do not want to use the `Breadcrumbs` class here directly, because we do not want it to be included in
110+
// bundles, if it is not used by the SDK.
111+
// 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
112+
// way for now.
113+
const breadcrumbIntegration = this.getIntegrationById(BREADCRUMB_INTEGRATION_ID) as Breadcrumbs | null;
114+
if (
115+
breadcrumbIntegration &&
116+
// We check for definedness of `options`, even though it is not strictly necessary, because that access to
117+
// `.sentry` below does not throw, in case users provided their own integration with id "Breadcrumbs" that does
118+
// not have an`options` field
119+
breadcrumbIntegration.options &&
120+
breadcrumbIntegration.options.sentry
121+
) {
122+
getCurrentHub().addBreadcrumb(
123+
{
124+
category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,
125+
event_id: event.event_id,
126+
level: event.level,
127+
message: getEventDescription(event),
128+
},
129+
{
130+
event,
131+
},
132+
);
133+
}
134+
135+
super.sendEvent(event, attachments);
101136
}
102137

103138
/**
104139
* @inheritDoc
105140
*/
106-
protected _sendEvent(event: Event, attachments: AttachmentWithData[]): void {
107-
const integration = this.getIntegration(Breadcrumbs);
108-
if (integration) {
109-
integration.addSentryBreadcrumb(event);
110-
}
111-
super._sendEvent(event, attachments);
141+
protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): PromiseLike<Event | null> {
142+
event.platform = event.platform || 'javascript';
143+
return super._prepareEvent(event, scope, hint);
112144
}
113145

114146
/**

packages/browser/src/integrations/breadcrumbs.ts

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
22
/* eslint-disable max-lines */
33
import { getCurrentHub } from '@sentry/core';
4-
import { Event, Integration } from '@sentry/types';
4+
import { Integration } from '@sentry/types';
55
import {
66
addInstrumentationHandler,
7-
getEventDescription,
87
getGlobalObject,
98
htmlTreeAsString,
109
parseUrl,
@@ -22,6 +21,8 @@ interface BreadcrumbsOptions {
2221
xhr: boolean;
2322
}
2423

24+
export const BREADCRUMB_INTEGRATION_ID = 'Breadcrumbs';
25+
2526
/**
2627
* Default Breadcrumbs instrumentations
2728
* TODO: Deprecated - with v6, this will be renamed to `Instrument`
@@ -30,21 +31,24 @@ export class Breadcrumbs implements Integration {
3031
/**
3132
* @inheritDoc
3233
*/
33-
public static id: string = 'Breadcrumbs';
34+
public static id: string = BREADCRUMB_INTEGRATION_ID;
3435

3536
/**
3637
* @inheritDoc
3738
*/
3839
public name: string = Breadcrumbs.id;
3940

40-
/** JSDoc */
41-
private readonly _options: BreadcrumbsOptions;
41+
/**
42+
* Options of the breadcrumbs integration.
43+
*/
44+
// This field is public, because we use it in the browser client to check if the `sentry` option is enabled.
45+
public readonly options: Readonly<BreadcrumbsOptions>;
4246

4347
/**
4448
* @inheritDoc
4549
*/
4650
public constructor(options?: Partial<BreadcrumbsOptions>) {
47-
this._options = {
51+
this.options = {
4852
console: true,
4953
dom: true,
5054
fetch: true,
@@ -55,26 +59,6 @@ export class Breadcrumbs implements Integration {
5559
};
5660
}
5761

58-
/**
59-
* Create a breadcrumb of `sentry` from the events themselves
60-
*/
61-
public addSentryBreadcrumb(event: Event): void {
62-
if (!this._options.sentry) {
63-
return;
64-
}
65-
getCurrentHub().addBreadcrumb(
66-
{
67-
category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,
68-
event_id: event.event_id,
69-
level: event.level,
70-
message: getEventDescription(event),
71-
},
72-
{
73-
event,
74-
},
75-
);
76-
}
77-
7862
/**
7963
* Instrument browser built-ins w/ breadcrumb capturing
8064
* - Console API
@@ -84,19 +68,19 @@ export class Breadcrumbs implements Integration {
8468
* - History API
8569
*/
8670
public setupOnce(): void {
87-
if (this._options.console) {
71+
if (this.options.console) {
8872
addInstrumentationHandler('console', _consoleBreadcrumb);
8973
}
90-
if (this._options.dom) {
91-
addInstrumentationHandler('dom', _domBreadcrumb(this._options.dom));
74+
if (this.options.dom) {
75+
addInstrumentationHandler('dom', _domBreadcrumb(this.options.dom));
9276
}
93-
if (this._options.xhr) {
77+
if (this.options.xhr) {
9478
addInstrumentationHandler('xhr', _xhrBreadcrumb);
9579
}
96-
if (this._options.fetch) {
80+
if (this.options.fetch) {
9781
addInstrumentationHandler('fetch', _fetchBreadcrumb);
9882
}
99-
if (this._options.history) {
83+
if (this.options.history) {
10084
addInstrumentationHandler('history', _historyBreadcrumb);
10185
}
10286
}

packages/core/src/baseclient.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,15 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
261261
}
262262
}
263263

264+
/**
265+
* Gets an installed integration by its `id`.
266+
*
267+
* @returns The installed integration or `undefined` if no integration with that `id` was installed.
268+
*/
269+
public getIntegrationById(integrationId: string): Integration | undefined {
270+
return this._integrations[integrationId];
271+
}
272+
264273
/**
265274
* @inheritDoc
266275
*/
@@ -544,15 +553,6 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
544553
}
545554
}
546555

547-
/**
548-
* Sends the passed event
549-
* @param event The Sentry event to send
550-
*/
551-
// TODO(v7): refactor: get rid of method?
552-
protected _sendEvent(event: Event, attachments?: AttachmentWithData[]): void {
553-
this.sendEvent(event, attachments);
554-
}
555-
556556
/**
557557
* Processes the event and logs an error in case of rejection
558558
* @param event
@@ -630,7 +630,7 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
630630
this._updateSessionFromEvent(session, processedEvent);
631631
}
632632

633-
this._sendEvent(processedEvent, this._attachmentsFromScope(scope));
633+
this.sendEvent(processedEvent, this._attachmentsFromScope(scope));
634634
return processedEvent;
635635
})
636636
.then(null, reason => {

packages/node/test/index.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { initAndBind, SDK_VERSION } from '@sentry/core';
22
import { getMainCarrier } from '@sentry/hub';
3-
import { Attachment, Integration } from '@sentry/types';
3+
import { AttachmentWithData,Integration } from '@sentry/types';
44
import * as domain from 'domain';
55

66
import {
@@ -76,7 +76,7 @@ describe('SentryNode', () => {
7676
});
7777

7878
describe('breadcrumbs', () => {
79-
let s: jest.SpyInstance<void, [Event, Attachment[]?]>;
79+
let s: jest.SpyInstance<void, [Event, AttachmentWithData[]?]>;
8080

8181
beforeEach(() => {
8282
s = jest.spyOn(NodeClient.prototype, 'sendEvent').mockImplementation(async () => Promise.resolve({ code: 200 }));
@@ -107,7 +107,7 @@ describe('SentryNode', () => {
107107
});
108108

109109
describe('capture', () => {
110-
let s: jest.SpyInstance<void, [Event, Attachment[]?]>;
110+
let s: jest.SpyInstance<void, [Event, AttachmentWithData[]?]>;
111111

112112
beforeEach(() => {
113113
s = jest.spyOn(NodeClient.prototype, 'sendEvent').mockImplementation(async () => Promise.resolve({ code: 200 }));

packages/utils/test/normalize.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import * as isModule from '../src/is';
66
import { normalize } from '../src/normalize';
77
import * as stacktraceModule from '../src/stacktrace';
8-
import { testOnlyIfNodeVersionAtLeast } from './testutils';
98

109
describe('normalize()', () => {
1110
describe('acts as a pass-through for simple-cases', () => {
@@ -48,7 +47,7 @@ describe('normalize()', () => {
4847
});
4948
});
5049

51-
testOnlyIfNodeVersionAtLeast(8)('extracts data from `Event` objects', () => {
50+
describe('extracts data from `Event` objects', () => {
5251
const isElement = jest.spyOn(isModule, 'isElement').mockReturnValue(true);
5352
const getAttribute = () => undefined;
5453

0 commit comments

Comments
 (0)