Skip to content

Commit 261920b

Browse files
committed
Merge branch 'master' into jb/feat/browser-profiling
2 parents a8cc694 + 4fb043e commit 261920b

File tree

137 files changed

+3312
-1900
lines changed

Some content is hidden

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

137 files changed

+3312
-1900
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ jobs:
424424
name: Nextjs (Node ${{ matrix.node }}) Tests
425425
needs: [job_get_metadata, job_build]
426426
if: needs.job_get_metadata.outputs.changed_nextjs == 'true' || github.event_name != 'pull_request'
427-
timeout-minutes: 15
427+
timeout-minutes: 25
428428
runs-on: ubuntu-20.04
429429
strategy:
430430
fail-fast: false

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,33 @@
44

55
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
66

7+
## 7.56.0
8+
9+
- feat(replay): Rework slow click & multi click detection (#8322)
10+
- feat(replay): Stop replay when event buffer exceeds max. size (#8315)
11+
- feat(replay): Consider `window.open` for slow clicks (#8308)
12+
- fix(core): Temporarily store debug IDs in stack frame and only put them into `debug_meta` before sending (#8347)
13+
- fix(remix): Extract deferred responses correctly in root loaders. (#8305)
14+
- fix(vue): Don't call `next` in Vue router 4 instrumentation (#8351)
15+
16+
## 7.55.2
17+
18+
- fix(replay): Stop exporting `EventType` from `@sentry-internal/rrweb` (#8334)
19+
- fix(serverless): Export captureCheckIn (#8333)
20+
21+
## 7.55.1
22+
23+
- fix(replay): Do not export types from `@sentry-internal/rrweb` (#8329)
24+
25+
## 7.55.0
26+
27+
- feat(replay): Capture slow clicks (GA) (#8298)
28+
- feat(replay): Improve types for replay recording events (#8224)
29+
- fix(nextjs): Strip query params from transaction names of navigations to unknown routes (#8278)
30+
- fix(replay): Ignore max session life for buffered sessions (#8258)
31+
- fix(sveltekit): Export captureCheckIn (#8313)
32+
- ref(svelte): Add Svelte 4 as a peer dependency (#8280)
33+
734
## 7.54.0
835

936
### Important Changes

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
3-
"version": "7.54.0",
3+
"version": "7.56.0",
44
"npmClient": "yarn",
55
"useWorkspaces": true
66
}

packages/angular-ivy/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry/angular-ivy",
3-
"version": "7.54.0",
3+
"version": "7.56.0",
44
"description": "Official Sentry SDK for Angular with full Ivy Support",
55
"repository": "git://github.com/getsentry/sentry-javascript.git",
66
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular-ivy",
@@ -21,9 +21,9 @@
2121
"rxjs": "^6.5.5 || ^7.x"
2222
},
2323
"dependencies": {
24-
"@sentry/browser": "7.54.0",
25-
"@sentry/types": "7.54.0",
26-
"@sentry/utils": "7.54.0",
24+
"@sentry/browser": "7.56.0",
25+
"@sentry/types": "7.56.0",
26+
"@sentry/utils": "7.56.0",
2727
"tslib": "^2.3.0"
2828
},
2929
"devDependencies": {

packages/angular-ivy/src/sdk.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { VERSION } from '@angular/core';
22
import type { BrowserOptions } from '@sentry/browser';
3-
import { init as browserInit, SDK_VERSION, setContext } from '@sentry/browser';
3+
import { defaultIntegrations, init as browserInit, SDK_VERSION, setContext } from '@sentry/browser';
44
import { logger } from '@sentry/utils';
55

66
import { IS_DEBUG_BUILD } from './flags';
@@ -21,6 +21,18 @@ export function init(options: BrowserOptions): void {
2121
version: SDK_VERSION,
2222
};
2323

24+
// Filter out TryCatch integration as it interferes with our Angular `ErrorHandler`:
25+
// TryCatch would catch certain errors before they reach the `ErrorHandler` and thus provide a
26+
// lower fidelity error than what `SentryErrorHandler` (see errorhandler.ts) would provide.
27+
// see:
28+
// - https://github.com/getsentry/sentry-javascript/issues/5417#issuecomment-1453407097
29+
// - https://github.com/getsentry/sentry-javascript/issues/2744
30+
if (options.defaultIntegrations === undefined) {
31+
options.defaultIntegrations = defaultIntegrations.filter(integration => {
32+
return integration.name !== 'TryCatch';
33+
});
34+
}
35+
2436
checkAndSetAngularVersion();
2537
browserInit(options);
2638
}

packages/angular/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry/angular",
3-
"version": "7.54.0",
3+
"version": "7.56.0",
44
"description": "Official Sentry SDK for Angular",
55
"repository": "git://github.com/getsentry/sentry-javascript.git",
66
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular",
@@ -21,9 +21,9 @@
2121
"rxjs": "^6.5.5 || ^7.x"
2222
},
2323
"dependencies": {
24-
"@sentry/browser": "7.54.0",
25-
"@sentry/types": "7.54.0",
26-
"@sentry/utils": "7.54.0",
24+
"@sentry/browser": "7.56.0",
25+
"@sentry/types": "7.56.0",
26+
"@sentry/utils": "7.56.0",
2727
"tslib": "^2.0.0"
2828
},
2929
"devDependencies": {

packages/angular/src/sdk.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { VERSION } from '@angular/core';
22
import type { BrowserOptions } from '@sentry/browser';
3-
import { init as browserInit, SDK_VERSION, setContext } from '@sentry/browser';
3+
import { defaultIntegrations, init as browserInit, SDK_VERSION, setContext } from '@sentry/browser';
44
import { logger } from '@sentry/utils';
55

66
import { IS_DEBUG_BUILD } from './flags';
@@ -21,6 +21,18 @@ export function init(options: BrowserOptions): void {
2121
version: SDK_VERSION,
2222
};
2323

24+
// Filter out TryCatch integration as it interferes with our Angular `ErrorHandler`:
25+
// TryCatch would catch certain errors before they reach the `ErrorHandler` and thus provide a
26+
// lower fidelity error than what `SentryErrorHandler` (see errorhandler.ts) would provide.
27+
// see:
28+
// - https://github.com/getsentry/sentry-javascript/issues/5417#issuecomment-1453407097
29+
// - https://github.com/getsentry/sentry-javascript/issues/2744
30+
if (options.defaultIntegrations === undefined) {
31+
options.defaultIntegrations = defaultIntegrations.filter(integration => {
32+
return integration.name !== 'TryCatch';
33+
});
34+
}
35+
2436
checkAndSetAngularVersion();
2537
browserInit(options);
2638
}

packages/angular/src/tracing.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { ActivatedRouteSnapshot, Event, RouterState } from '@angular/router
55
// Duplicated import to work around a TypeScript bug where it'd complain that `Router` isn't imported as a type.
66
// We need to import it as a value to satisfy Angular dependency injection. So:
77
// eslint-disable-next-line @typescript-eslint/consistent-type-imports, import/no-duplicates
8-
import { Router } from '@angular/router';
8+
import { NavigationCancel, NavigationError, Router } from '@angular/router';
99
// eslint-disable-next-line import/no-duplicates
1010
import { NavigationEnd, NavigationStart, ResolveEnd } from '@angular/router';
1111
import { getCurrentHub, WINDOW } from '@sentry/browser';
@@ -131,7 +131,9 @@ export class TraceService implements OnDestroy {
131131
);
132132

133133
public navEnd$: Observable<Event> = this._router.events.pipe(
134-
filter(event => event instanceof NavigationEnd),
134+
filter(
135+
event => event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError,
136+
),
135137
tap(() => {
136138
if (this._routingSpan) {
137139
runOutsideAngular(() => {

packages/angular/test/sdk.test.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as SentryBrowser from '@sentry/browser';
22

3-
import { init } from '../src/sdk';
3+
import { defaultIntegrations, init } from '../src/index';
44

55
describe('init', () => {
66
it('sets the Angular version (if available) in the global scope', () => {
@@ -13,4 +13,33 @@ describe('init', () => {
1313
expect(setContextSpy).toHaveBeenCalledTimes(1);
1414
expect(setContextSpy).toHaveBeenCalledWith('angular', { version: 10 });
1515
});
16+
17+
describe('filtering out the `TryCatch` integration', () => {
18+
const browserInitSpy = jest.spyOn(SentryBrowser, 'init');
19+
20+
beforeEach(() => {
21+
browserInitSpy.mockClear();
22+
});
23+
24+
it('filters if `defaultIntegrations` is not set', () => {
25+
init({});
26+
27+
expect(browserInitSpy).toHaveBeenCalledTimes(1);
28+
29+
const options = browserInitSpy.mock.calls[0][0] || {};
30+
expect(options.defaultIntegrations).not.toContainEqual(expect.objectContaining({ name: 'TryCatch' }));
31+
});
32+
33+
it.each([false as const, defaultIntegrations])(
34+
"doesn't filter if `defaultIntegrations` is set to %s",
35+
defaultIntegrations => {
36+
init({ defaultIntegrations });
37+
38+
expect(browserInitSpy).toHaveBeenCalledTimes(1);
39+
40+
const options = browserInitSpy.mock.calls[0][0] || {};
41+
expect(options.defaultIntegrations).toEqual(defaultIntegrations);
42+
},
43+
);
44+
});
1645
});

packages/angular/test/tracing.test.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component } from '@angular/core';
2-
import type { ActivatedRouteSnapshot } from '@angular/router';
2+
import type { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
33
import type { Hub } from '@sentry/types';
44

55
import { instrumentAngularRouting, TraceClassDecorator, TraceDirective, TraceMethodDecorator } from '../src';
@@ -185,6 +185,66 @@ describe('Angular Tracing', () => {
185185
env.destroy();
186186
});
187187

188+
it('finishes routing span on navigation error', async () => {
189+
const customStartTransaction = jest.fn(defaultStartTransaction);
190+
191+
const env = await TestEnv.setup({
192+
customStartTransaction,
193+
routes: [
194+
{
195+
path: '',
196+
component: AppComponent,
197+
},
198+
],
199+
useTraceService: true,
200+
});
201+
202+
const finishMock = jest.fn();
203+
transaction.startChild = jest.fn(() => ({
204+
finish: finishMock,
205+
}));
206+
207+
await env.navigateInAngular('/somewhere');
208+
209+
expect(finishMock).toHaveBeenCalledTimes(1);
210+
211+
env.destroy();
212+
});
213+
214+
it('finishes routing span on navigation cancel', async () => {
215+
const customStartTransaction = jest.fn(defaultStartTransaction);
216+
217+
class CanActivateGuard implements CanActivate {
218+
canActivate(_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): boolean {
219+
return false;
220+
}
221+
}
222+
223+
const env = await TestEnv.setup({
224+
customStartTransaction,
225+
routes: [
226+
{
227+
path: 'cancel',
228+
component: AppComponent,
229+
canActivate: [CanActivateGuard],
230+
},
231+
],
232+
useTraceService: true,
233+
additionalProviders: [{ provide: CanActivateGuard, useClass: CanActivateGuard }],
234+
});
235+
236+
const finishMock = jest.fn();
237+
transaction.startChild = jest.fn(() => ({
238+
finish: finishMock,
239+
}));
240+
241+
await env.navigateInAngular('/cancel');
242+
243+
expect(finishMock).toHaveBeenCalledTimes(1);
244+
245+
env.destroy();
246+
});
247+
188248
describe('URL parameterization', () => {
189249
it.each([
190250
[

packages/angular/test/utils/index.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Provider } from '@angular/core';
12
import { Component, NgModule } from '@angular/core';
23
import type { ComponentFixture } from '@angular/core/testing';
34
import { TestBed } from '@angular/core/testing';
@@ -47,6 +48,7 @@ export class TestEnv {
4748
startTransactionOnPageLoad?: boolean;
4849
startTransactionOnNavigation?: boolean;
4950
useTraceService?: boolean;
51+
additionalProviders?: Provider[];
5052
}): Promise<TestEnv> {
5153
instrumentAngularRouting(
5254
conf.customStartTransaction || jest.fn(),
@@ -60,14 +62,16 @@ export class TestEnv {
6062
TestBed.configureTestingModule({
6163
imports: [AppModule, RouterTestingModule.withRoutes(routes)],
6264
declarations: [...(conf.components || []), AppComponent],
63-
providers: useTraceService
65+
providers: (useTraceService
6466
? [
6567
{
6668
provide: TraceService,
6769
deps: [Router],
6870
},
71+
...(conf.additionalProviders || []),
6972
]
70-
: [],
73+
: []
74+
).concat(...(conf.additionalProviders || [])),
7175
});
7276

7377
const router: Router = TestBed.inject(Router);
@@ -80,10 +84,16 @@ export class TestEnv {
8084
public async navigateInAngular(url: string): Promise<void> {
8185
return new Promise(resolve => {
8286
return this.fixture.ngZone?.run(() => {
83-
void this.router.navigateByUrl(url).then(() => {
84-
this.fixture.detectChanges();
85-
resolve();
86-
});
87+
void this.router
88+
.navigateByUrl(url)
89+
.then(() => {
90+
this.fixture.detectChanges();
91+
resolve();
92+
})
93+
.catch(() => {
94+
this.fixture.detectChanges();
95+
resolve();
96+
});
8797
});
8898
});
8999
}

packages/browser-integration-tests/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry-internal/browser-integration-tests",
3-
"version": "7.54.0",
3+
"version": "7.56.0",
44
"main": "index.js",
55
"license": "MIT",
66
"engines": {

packages/browser-integration-tests/suites/replay/bufferMode/test.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ sentryTest(
2525
let errorEventId: string | undefined;
2626
const reqPromise0 = waitForReplayRequest(page, 0);
2727
const reqPromise1 = waitForReplayRequest(page, 1);
28-
const reqPromise2 = waitForReplayRequest(page, 2);
2928
const reqErrorPromise = waitForErrorRequest(page);
3029

3130
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
@@ -101,18 +100,14 @@ sentryTest(
101100

102101
// Switches to session mode and then goes to background
103102
const req1 = await reqPromise1;
104-
const req2 = await reqPromise2;
105-
expect(callsToSentry).toBeGreaterThanOrEqual(5);
103+
expect(callsToSentry).toBeGreaterThanOrEqual(4);
106104

107105
const event0 = getReplayEvent(req0);
108106
const content0 = getReplayRecordingContent(req0);
109107

110108
const event1 = getReplayEvent(req1);
111109
const content1 = getReplayRecordingContent(req1);
112110

113-
const event2 = getReplayEvent(req2);
114-
const content2 = getReplayRecordingContent(req2);
115-
116111
expect(event0).toEqual(
117112
getExpectedReplayEvent({
118113
error_ids: [errorEventId!],
@@ -157,17 +152,7 @@ sentryTest(
157152

158153
// From switching to session mode
159154
expect(content1.fullSnapshots).toHaveLength(1);
160-
161-
expect(event2).toEqual(
162-
getExpectedReplayEvent({
163-
replay_type: 'buffer', // although we're in session mode, we still send 'buffer' as replay_type
164-
segment_id: 2,
165-
urls: [],
166-
}),
167-
);
168-
169-
expect(content2.fullSnapshots).toHaveLength(0);
170-
expect(content2.breadcrumbs).toEqual(expect.arrayContaining([expectedClickBreadcrumb]));
155+
expect(content1.breadcrumbs).toEqual(expect.arrayContaining([expectedClickBreadcrumb]));
171156
},
172157
);
173158

0 commit comments

Comments
 (0)