Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@mantine/hooks": "^7.11.2",
"@octokit/rest": "^22.0.0",
"@reduxjs/toolkit": "^1.9.7",
"@sentry/browser": "^8.33.0",
"@sentry/react": "^10.5.0",
"@sourceacademy/c-slang": "^1.0.21",
"@sourceacademy/sharedb-ace": "2.1.1",
"@sourceacademy/sling-client": "^0.1.0",
Expand Down
3 changes: 2 additions & 1 deletion rsbuild.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export default defineConfig({
output: {
distPath: {
root: './build'
}
},
sourceMap: true
}
});
3 changes: 2 additions & 1 deletion src/commons/application/ApplicationWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Classes, NonIdealState } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import * as Sentry from '@sentry/react';
import classNames from 'classnames';
import { useEffect, useMemo, useState } from 'react';
import { useDispatch } from 'react-redux';
Expand Down Expand Up @@ -37,7 +38,7 @@ const ApplicationWrapper: React.FC = () => {
? playgroundOnlyRouterConfig
: getFullAcademyRouterConfig({ name, isLoggedIn, courseId, academyRoutes });

const r = createBrowserRouter(routerConfig);
const r = Sentry.wrapCreateBrowserRouterV7(createBrowserRouter)(routerConfig);
dispatch(updateReactRouter(r));

return r;
Expand Down
3 changes: 2 additions & 1 deletion src/commons/application/__tests__/Application.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { Mock, vi } from 'vitest';

import Application from '../Application';

vi.mock('react-redux', () => ({
vi.mock('react-redux', async importOriginal => ({
...(await importOriginal()),
useDispatch: vi.fn(),
useSelector: vi.fn()
}));
Expand Down
2 changes: 1 addition & 1 deletion src/commons/editor/UseShareAce.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
AceMultiSelectionManager,
AceRadarView
} from '@convergencelabs/ace-collab-ext';
import * as Sentry from '@sentry/browser';
import * as Sentry from '@sentry/react';
import sharedbAce from '@sourceacademy/sharedb-ace';
import type SharedbAceBinding from '@sourceacademy/sharedb-ace/binding';
import { CollabEditingAccess } from '@sourceacademy/sharedb-ace/types';
Expand Down
7 changes: 4 additions & 3 deletions src/commons/navigationBar/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import { IconName, IconNames } from '@blueprintjs/icons';
import classNames from 'classnames';
import React, { useMemo, useState } from 'react';
import { Translation } from 'react-i18next';
import { Location, NavLink, Route, Routes, useLocation } from 'react-router';
import { type Location, NavLink, Route, useLocation } from 'react-router';
import { i18nDefaultLangKeys } from 'src/i18n/i18next';
import { SentryRoutes } from 'src/routes/routerConfig';
import classes from 'src/styles/NavigationBar.module.scss';

import Dropdown from '../dropdown/Dropdown';
Expand Down Expand Up @@ -312,7 +313,7 @@ const NavigationBar: React.FC = () => {
{commonNavbarRight}
</Navbar>

<Routes>
<SentryRoutes>
<Route path="/playground/*" element={null} />
<Route path="/contributors" element={null} />
<Route path="/courses/:courseId/sourcecast" element={null} />
Expand All @@ -327,7 +328,7 @@ const NavigationBar: React.FC = () => {
) : null
}
/>
</Routes>
</SentryRoutes>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Mock, vi } from 'vitest';
import { Role } from '../../../application/ApplicationTypes';
import AcademyNavigationBar from '../AcademyNavigationBar';

vi.mock('react-redux', () => ({
vi.mock('react-redux', async importOriginal => ({
...(await importOriginal()),
useSelector: vi.fn()
}));
const useSelectorMock = useTypedSelector as Mock;
Expand Down
2 changes: 1 addition & 1 deletion src/commons/sagas/LoginSaga.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { setUser } from '@sentry/browser';
import { setUser } from '@sentry/react';
import { call, select } from 'redux-saga/effects';
import Messages, { sendToWebview } from 'src/features/vscode/messages';

Expand Down
2 changes: 1 addition & 1 deletion src/commons/sagas/SafeEffects.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ActionMatchingPattern } from '@redux-saga/types';
import * as Sentry from '@sentry/browser';
import * as Sentry from '@sentry/react';
import {
type ActionPattern,
type ForkEffect,
Expand Down
6 changes: 3 additions & 3 deletions src/commons/sagas/__tests__/SafeEffects.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as Sentry from '@sentry/browser';
import * as Sentry from '@sentry/react';
import { call } from 'redux-saga/effects';
import { expectSaga } from 'redux-saga-test-plan';
import { vi } from 'vitest';

import { wrapSaga } from '../SafeEffects';

vi.mock('@sentry/browser', async () => ({
...(await vi.importActual('../../../../node_modules/@sentry/browser')),
vi.mock('@sentry/react', async importOriginal => ({
...(await importOriginal()),
captureException: vi.fn()
}));

Expand Down
21 changes: 19 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ import 'src/i18n/i18n';
import 'src/styles/index.scss';

import { Button, OverlaysProvider } from '@blueprintjs/core';
import * as Sentry from '@sentry/browser';
import * as Sentry from '@sentry/react';
import { setModulesStaticURL } from 'js-slang/dist/modules/loader';
import { useEffect } from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType
} from 'react-router';
import Constants, { Links } from 'src/commons/utils/Constants';
import { showWarningMessage } from 'src/commons/utils/notifications/NotificationsHelper';
import { register as registerServiceWorker } from 'src/commons/utils/RegisterServiceWorker';
Expand All @@ -19,7 +26,17 @@ if (Constants.sentryDsn) {
Sentry.init({
dsn: Constants.sentryDsn,
environment: Constants.sourceAcademyEnvironment,
release: `cadet-frontend@${Constants.sourceAcademyVersion}`
release: `cadet-frontend@${Constants.sourceAcademyVersion}`,
integrations: [
Sentry.reactRouterV7BrowserTracingIntegration({
useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes
}),
Sentry.replayIntegration()
]
});
const userId = store.getState().session.userId;
Sentry.setUser(typeof userId !== 'undefined' ? { id: userId.toString() } : null);
Expand Down
7 changes: 4 additions & 3 deletions src/pages/achievement/Achievement.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { Route, Routes } from 'react-router';
import { Route } from 'react-router';
import { useTypedSelector } from 'src/commons/utils/Hooks';
import { SentryRoutes } from 'src/routes/routerConfig';

import { Role } from '../../commons/application/ApplicationTypes';
import NotFound from '../notFound/NotFound';
Expand All @@ -14,11 +15,11 @@ const Achievement: React.FC = () => {
role === Role.Admin || role === Role.Staff ? <AchievementControl /> : <NotFound />;

return (
<Routes>
<SentryRoutes>
<Route path="/" element={<AchievementDashboard />}></Route>
<Route path="control" element={toAchievementControl}></Route>
<Route path="*" element={<NotFound />} />
</Routes>
</SentryRoutes>
);
};

Expand Down
1 change: 1 addition & 0 deletions src/pages/createStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function createStore() {
// We already provide the generic type argument, so we put
// `as any` to prevent excessively long type inference
preloadedState: initialStore as any
// TODO: Sentry Redux integration once we update to RTK2
});
sagaMiddleware.run(MainSaga);

Expand Down
7 changes: 4 additions & 3 deletions src/pages/leaderboard/Leaderboard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { Navigate, Route, Routes } from 'react-router';
import { Navigate, Route } from 'react-router';
import { useTypedSelector } from 'src/commons/utils/Hooks';
import { SentryRoutes } from 'src/routes/routerConfig';

import NotFound from '../notFound/NotFound';
import OverallLeaderboardWrapper from './subcomponents/OverallLeaderboardWrapper';
Expand All @@ -22,7 +23,7 @@ const Leaderboard: React.FC = () => {
const baseLink = `/courses/${courseId}/leaderboard`;

return (
<Routes>
<SentryRoutes>
<Route
path="/"
element={
Expand All @@ -46,7 +47,7 @@ const Leaderboard: React.FC = () => {
)
}
></Route>
</Routes>
</SentryRoutes>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { Navigate, Route, Routes, useLocation, useParams } from 'react-router';
import { Navigate, Route, useLocation, useParams } from 'react-router';
import { useTypedSelector } from 'src/commons/utils/Hooks';
import LeaderboardActions from 'src/features/leaderboard/LeaderboardActions';
import { LeaderboardContestDetails } from 'src/features/leaderboard/LeaderboardTypes';
import type { LeaderboardContestDetails } from 'src/features/leaderboard/LeaderboardTypes';
import { SentryRoutes } from 'src/routes/routerConfig';

import NotFound from '../../notFound/NotFound';
import ContestLeaderboard from './ContestLeaderboard';
Expand All @@ -28,7 +29,7 @@ const ContestLeaderboardWrapper: React.FC = () => {
const baseLink = `/courses/${courseId}/leaderboard`;

return (
<Routes>
<SentryRoutes>
<Route
path="/:id/score"
element={
Expand Down Expand Up @@ -71,7 +72,7 @@ const ContestLeaderboardWrapper: React.FC = () => {
></Route>

<Route path="*" element={<Navigate to={baseLink} />}></Route>
</Routes>
</SentryRoutes>
);
};

Expand Down
5 changes: 4 additions & 1 deletion src/routes/routerConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Navigate, redirect, RouteObject } from 'react-router';
import * as Sentry from '@sentry/react';
import { Navigate, redirect, type RouteObject, Routes } from 'react-router';
import Constants from 'src/commons/utils/Constants';

import Application from '../commons/application/Application';
Expand Down Expand Up @@ -150,3 +151,5 @@ export const getFullAcademyRouterConfig = ({
}
];
};

export const SentryRoutes = Sentry.withSentryReactRouterV7Routing(Routes);
85 changes: 49 additions & 36 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3183,61 +3183,74 @@ __metadata:
languageName: node
linkType: hard

"@sentry-internal/browser-utils@npm:8.55.0":
version: 8.55.0
resolution: "@sentry-internal/browser-utils@npm:8.55.0"
"@sentry-internal/browser-utils@npm:10.5.0":
version: 10.5.0
resolution: "@sentry-internal/browser-utils@npm:10.5.0"
dependencies:
"@sentry/core": "npm:8.55.0"
checksum: 10c0/201eb94ee64a4dab058153c64dd4ce0af082f3c3bc84a5441cdadf344d9554a0a67c9d9dfdff720eb42de214d67d734d5bda25a050c2efd59c03f60562bb139a
"@sentry/core": "npm:10.5.0"
checksum: 10c0/ada1cfa7f626c7272f67f10cd828e17d2054e64230c10e35b06a5d07d303c8d8dc0efd73d8624ab0f1098941009b29d239a8be9529fac58aeb0f127dadf0a1ac
languageName: node
linkType: hard

"@sentry-internal/feedback@npm:8.55.0":
version: 8.55.0
resolution: "@sentry-internal/feedback@npm:8.55.0"
"@sentry-internal/feedback@npm:10.5.0":
version: 10.5.0
resolution: "@sentry-internal/feedback@npm:10.5.0"
dependencies:
"@sentry/core": "npm:8.55.0"
checksum: 10c0/2515c4eca6226e3df28a498f7f3771d7820556887bf8c06f2d5469c92474cf72ed81eaa0079f6bcf46905c54315e2631bb7b9ed7ed6741cf9b7f73a3f4875acc
"@sentry/core": "npm:10.5.0"
checksum: 10c0/a7752a08a5452b2c079f0df1c80e8b51875332cfe8fa0478095f0684dbf365432e6c0dfc1564cff6d35fd1a6f6d8e91705ba28b2e5437d133b7af88ef5120fa6
languageName: node
linkType: hard

"@sentry-internal/replay-canvas@npm:8.55.0":
version: 8.55.0
resolution: "@sentry-internal/replay-canvas@npm:8.55.0"
"@sentry-internal/replay-canvas@npm:10.5.0":
version: 10.5.0
resolution: "@sentry-internal/replay-canvas@npm:10.5.0"
dependencies:
"@sentry-internal/replay": "npm:8.55.0"
"@sentry/core": "npm:8.55.0"
checksum: 10c0/6f3c619ede1de47635035f74477dd5a11e5c2cac9d0906448a7fffb6dad1c5bd9a49a594fbc2a51ba3b1859a91f60e08ab6de2d9961ccbaa343af580f1d13fb1
"@sentry-internal/replay": "npm:10.5.0"
"@sentry/core": "npm:10.5.0"
checksum: 10c0/306f93be5a17b1d83cc2143b33558d861fe6ad40170e33a4a5b71af524fa7a2453b2b7a17172faa2d98fd80b7aa4cc233cbf8ce6e261d3803f317be7206fa0ff
languageName: node
linkType: hard

"@sentry-internal/replay@npm:8.55.0":
version: 8.55.0
resolution: "@sentry-internal/replay@npm:8.55.0"
"@sentry-internal/replay@npm:10.5.0":
version: 10.5.0
resolution: "@sentry-internal/replay@npm:10.5.0"
dependencies:
"@sentry-internal/browser-utils": "npm:8.55.0"
"@sentry/core": "npm:8.55.0"
checksum: 10c0/320fd5685c1e84c5feebaa88fc72afd0bd5189b95d690f8c24301cd8b13789431b2c1d28e3e5a93f669ca3b80cdc830e672723aa7a28ff8f0b901674ce0c0529
"@sentry-internal/browser-utils": "npm:10.5.0"
"@sentry/core": "npm:10.5.0"
checksum: 10c0/3edb71b2d5ab27d081996c2b3358a134322f2f271c6887ba8392558fbe8f2a8e68092d04bf73b9354c0f9f058ab8eca59adb8d35a0772ace53988b1856ec910b
languageName: node
linkType: hard

"@sentry/browser@npm:^8.33.0":
version: 8.55.0
resolution: "@sentry/browser@npm:8.55.0"
"@sentry/browser@npm:10.5.0":
version: 10.5.0
resolution: "@sentry/browser@npm:10.5.0"
dependencies:
"@sentry-internal/browser-utils": "npm:8.55.0"
"@sentry-internal/feedback": "npm:8.55.0"
"@sentry-internal/replay": "npm:8.55.0"
"@sentry-internal/replay-canvas": "npm:8.55.0"
"@sentry/core": "npm:8.55.0"
checksum: 10c0/a485de7385851c96ed4c2291d065594aeea2076b11b3b113f4866fdbff1522524abd97664f0d0b011e0eff6c4986a556f080bccfa1b770466c6afcb6122dfbaf
"@sentry-internal/browser-utils": "npm:10.5.0"
"@sentry-internal/feedback": "npm:10.5.0"
"@sentry-internal/replay": "npm:10.5.0"
"@sentry-internal/replay-canvas": "npm:10.5.0"
"@sentry/core": "npm:10.5.0"
checksum: 10c0/5fe68957a29b84f703ab02a4e4fb59c36ca08eb6e8c057a94690e31a05ebd42ced8029d3bc44095d1194e82d82c3455d7a9847523be75d1c438af930f63b8463
languageName: node
linkType: hard

"@sentry/core@npm:8.55.0":
version: 8.55.0
resolution: "@sentry/core@npm:8.55.0"
checksum: 10c0/51c1768f0bd940a060787b402dba9df3347c918ea4c0fdc300d45c37703ebbf6f7adee9fff332cfd6b23372b33c46e6d2f31a04227762d490aaddc14773894a0
"@sentry/core@npm:10.5.0":
version: 10.5.0
resolution: "@sentry/core@npm:10.5.0"
checksum: 10c0/e0b29c6647897cf6dc5f0b99c29f2bbad62ba4db57d699790f39028f0124e388728b955d794d4c07cb6f93b17e5011095c9927bf111a6f62caa9147034ef56e1
languageName: node
linkType: hard

"@sentry/react@npm:^10.5.0":
version: 10.5.0
resolution: "@sentry/react@npm:10.5.0"
dependencies:
"@sentry/browser": "npm:10.5.0"
"@sentry/core": "npm:10.5.0"
hoist-non-react-statics: "npm:^3.3.2"
peerDependencies:
react: ^16.14.0 || 17.x || 18.x || 19.x
checksum: 10c0/b42fed203599d5d9e3b3d61adf9a57da0e00e1bf2e69c5d1bd8664310ff600ed53dda3cbbb5f2f5956dd10e5c52e903828b508c9d8cd41289bbdd9050948f574
languageName: node
linkType: hard

Expand Down Expand Up @@ -7543,7 +7556,7 @@ __metadata:
"@rsbuild/plugin-react": "npm:^1.3.0"
"@rsbuild/plugin-sass": "npm:^1.3.1"
"@rsbuild/plugin-svgr": "npm:^1.2.0"
"@sentry/browser": "npm:^8.33.0"
"@sentry/react": "npm:^10.5.0"
"@sourceacademy/c-slang": "npm:^1.0.21"
"@sourceacademy/sharedb-ace": "npm:2.1.1"
"@sourceacademy/sling-client": "npm:^0.1.0"
Expand Down
Loading