Skip to content

Commit 1a8c379

Browse files
authored
CRAFT-1995: update @sentry to v8 (#3904)
* chore(deps): update @sentry to v8 * chore(deps): adjust type * chore(changeset): add changeset * chore(changeset): enhance changeset and comments * chore(deps): correct rebase
1 parent 7d71e06 commit 1a8c379

File tree

6 files changed

+148
-62
lines changed

6 files changed

+148
-62
lines changed

.changeset/happy-days-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@commercetools-frontend/sentry': patch
3+
---
4+
5+
Update @sentry/react to v8 for React 19 compatibility. Migrate deprecated `configureScope` API to `getCurrentScope()` and update type signatures to satisfy v8 requirements.

packages/sentry/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
"@babel/runtime-corejs3": "^7.22.15",
2323
"@commercetools-frontend/browser-history": "24.13.0",
2424
"@commercetools-frontend/constants": "24.13.0",
25-
"@sentry/browser": "7.120.4",
26-
"@sentry/react": "7.120.4",
27-
"@sentry/types": "7.120.4",
25+
"@sentry/browser": "8.55.0",
26+
"@sentry/react": "8.55.0",
27+
"@sentry/types": "8.55.0",
2828
"@types/prop-types": "^15.7.5",
2929
"@types/react": "^19.0.3",
3030
"prop-types": "15.8.1"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import * as Sentry from '@sentry/react';
2+
import { render } from '@testing-library/react';
3+
import type { ApplicationWindow } from '@commercetools-frontend/constants';
4+
5+
import SentryUserLogoutTracker from './sentry-user-logout-tracker';
6+
7+
declare let window: ApplicationWindow;
8+
9+
jest.mock('@sentry/react');
10+
11+
describe('SentryUserLogoutTracker', () => {
12+
beforeEach(() => {
13+
// Reset mocks and window state before each test
14+
jest.clearAllMocks();
15+
delete window.app?.trackingSentry;
16+
// Mock getCurrentScope to return an object with a clear method
17+
(Sentry.getCurrentScope as jest.Mock) = jest.fn(() => ({
18+
clear: jest.fn(),
19+
}));
20+
});
21+
22+
describe('when Sentry tracking is enabled', () => {
23+
it('should clear the Sentry scope on mount', () => {
24+
window.app = { trackingSentry: 'enabled' } as ApplicationWindow['app'];
25+
const clearMock = jest.fn();
26+
(Sentry.getCurrentScope as jest.Mock).mockReturnValue({
27+
clear: clearMock,
28+
});
29+
30+
render(<SentryUserLogoutTracker />);
31+
32+
expect(Sentry.getCurrentScope).toHaveBeenCalled();
33+
expect(clearMock).toHaveBeenCalled();
34+
});
35+
});
36+
37+
describe('when Sentry tracking is not enabled', () => {
38+
it('should do nothing when trackingSentry is not set', () => {
39+
window.app = {} as ApplicationWindow['app'];
40+
const clearMock = jest.fn();
41+
(Sentry.getCurrentScope as jest.Mock).mockReturnValue({
42+
clear: clearMock,
43+
});
44+
45+
render(<SentryUserLogoutTracker />);
46+
47+
expect(Sentry.getCurrentScope).not.toHaveBeenCalled();
48+
expect(clearMock).not.toHaveBeenCalled();
49+
});
50+
51+
it('should not clear the Sentry scope when trackingSentry is undefined', () => {
52+
window.app = { trackingSentry: undefined } as ApplicationWindow['app'];
53+
const clearMock = jest.fn();
54+
(Sentry.getCurrentScope as jest.Mock).mockReturnValue({
55+
clear: clearMock,
56+
});
57+
58+
render(<SentryUserLogoutTracker />);
59+
60+
expect(Sentry.getCurrentScope).not.toHaveBeenCalled();
61+
expect(clearMock).not.toHaveBeenCalled();
62+
});
63+
});
64+
});

packages/sentry/src/sentry-user-logout-tracker/sentry-user-logout-tracker.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ class SentryUserLogoutTracker extends Component {
1010
// When the user is not logged in anymore (e.g. on logout) we still track
1111
// errors but without the user data in context.
1212
if (window.app.trackingSentry) {
13-
Sentry.configureScope((scope) => {
14-
scope.clear();
15-
});
13+
Sentry.getCurrentScope().clear();
1614
}
1715
}
1816
render() {

packages/sentry/src/sentry.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import * as Sentry from '@sentry/react';
22
// eslint-disable-next-line import/order
33
import { globalHandlersIntegration } from '@sentry/browser'; // Must import after `@sentry/react`
4-
import type { Extra, Extras, Event } from '@sentry/types';
4+
import type {
5+
Extra,
6+
Extras,
7+
Event,
8+
ErrorEvent as SentryErrorEvent,
9+
} from '@sentry/types';
510
import history from '@commercetools-frontend/browser-history';
611
import type { ApplicationWindow } from '@commercetools-frontend/constants';
712

@@ -103,8 +108,10 @@ export const boot = () => {
103108
// we can implement the `tracesSampler` function.
104109
// https://docs.sentry.io/platforms/javascript/guides/react/configuration/sampling/#sampling-transaction-events
105110
tracesSampleRate: 0.05,
106-
beforeSend(event) {
107-
return redactUnsafeEventFields(event);
111+
// v8 requires the hint parameter which provides additional error context.
112+
// We only redact PII from event fields, so hint is unused for now.
113+
beforeSend(event, _hint) {
114+
return redactUnsafeEventFields(event) as SentryErrorEvent;
108115
},
109116
});
110117
const sentryScope = Sentry.getCurrentScope();
@@ -160,7 +167,7 @@ export const reportErrorToSentry = (
160167
// The error stack should be available in Sentry, so there is no
161168
// need to print it in the console as well.
162169
// We just notify that an error occurred and provide the error ID.
163-
console.error(`[SENTRY]: An error occured (ID: ${errorId}).`);
170+
console.error(`[SENTRY]: An error occurred (ID: ${errorId}).`);
164171
return errorId;
165172
}
166173

pnpm-lock.yaml

Lines changed: 64 additions & 52 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)