Skip to content

Commit 64ee3a9

Browse files
committed
#1250: Surrounded uncaught mutate asyncs in try catches
1 parent 3a889bf commit 64ee3a9

5 files changed

Lines changed: 83 additions & 38 deletions

File tree

src/frontend/src/components/CheckList.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Tooltip } from '@mui/material';
1414
import { User } from 'shared';
1515
import NERModal from './NERModal';
1616
import { fullNamePipe } from '../utils/pipes';
17+
import { useToast } from '../hooks/toasts.hooks';
1718

1819
export type CheckListItem = {
1920
id: number;
@@ -34,14 +35,21 @@ const CheckList: React.FC<CheckListProps> = ({ title, items, isDisabled }) => {
3435
const { isLoading, mutateAsync } = useCheckDescriptionBullet();
3536
const [showConfirm, setShowConfirm] = useState<boolean>(false);
3637
const [currIdx, setCurrIdx] = useState<number>(-1);
38+
const toast = useToast();
3739

3840
const handleUncheck = async (idx: number) => {
3941
await handleCheck(idx);
4042
setShowConfirm(false);
4143
};
4244

4345
const handleCheck = async (idx: number) => {
44-
await mutateAsync({ userId: auth.user!.userId, descriptionId: items[idx].id });
46+
try {
47+
await mutateAsync({ userId: auth.user!.userId, descriptionId: items[idx].id });
48+
} catch (e) {
49+
if (e instanceof Error) {
50+
toast.error(e.message);
51+
}
52+
}
4553
};
4654

4755
items.sort((a: CheckListItem, b: CheckListItem) => {

src/frontend/src/hooks/auth.hooks.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,38 @@ import { AuthenticatedUser } from 'shared';
88
import { AuthContext } from '../app/AppContextAuth';
99
import { useLogUserIn, useLogUserInDev } from './users.hooks';
1010
import { Auth } from '../utils/types';
11+
import { useToast } from './toasts.hooks';
1112

1213
// Provider hook that creates auth object and handles state
1314
export const useProvideAuth = () => {
1415
const { isLoading, mutateAsync } = useLogUserIn();
1516
const { isLoading: isLoadingDev, mutateAsync: mutateAsyncDev } = useLogUserInDev();
1617
const [user, setUser] = useState<AuthenticatedUser | undefined>(undefined);
18+
const toast = useToast();
1719

1820
const devSignin = async (userId: number) => {
19-
const user = await mutateAsyncDev(userId);
20-
setUser(user);
21-
localStorage.setItem('devUserId', userId.toString());
22-
return user;
21+
try {
22+
const user = await mutateAsyncDev(userId);
23+
setUser(user);
24+
localStorage.setItem('devUserId', userId.toString());
25+
return user;
26+
} catch (e) {
27+
if (e instanceof Error) {
28+
toast.error(e.message);
29+
}
30+
}
2331
};
2432

2533
const signin = async (id_token: string) => {
26-
const user = await mutateAsync(id_token);
27-
setUser(user);
28-
return user;
34+
try {
35+
const user = await mutateAsync(id_token);
36+
setUser(user);
37+
return user;
38+
} catch (e) {
39+
if (e instanceof Error) {
40+
toast.error(e.message);
41+
}
42+
}
2943
};
3044

3145
const signout = () => {

src/frontend/src/pages/ChangeRequestDetailPage/ProposedSolutionsList.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import ErrorPage from '../ErrorPage';
1313
import LoadingIndicator from '../../components/LoadingIndicator';
1414
import { useAuth } from '../../hooks/auth.hooks';
1515
import { Button } from '@mui/material';
16+
import { useToast } from '../../hooks/toasts.hooks';
1617

1718
interface ProposedSolutionsListProps {
1819
proposedSolutions: ProposedSolution[];
@@ -24,6 +25,7 @@ const ProposedSolutionsList: React.FC<ProposedSolutionsListProps> = ({ proposedS
2425
const [showEditableForm, setShowEditableForm] = useState<boolean>(false);
2526
const auth = useAuth();
2627
const { isLoading, isError, error, mutateAsync } = useCreateProposeSolution();
28+
const toast = useToast();
2729

2830
if (isLoading || !auth.user) return <LoadingIndicator />;
2931
if (isError) return <ErrorPage message={error?.message} />;
@@ -34,15 +36,21 @@ const ProposedSolutionsList: React.FC<ProposedSolutionsListProps> = ({ proposedS
3436
setShowEditableForm(false);
3537
const { description, timelineImpact, scopeImpact, budgetImpact } = data;
3638

37-
// send the details of new proposed solution to the backend database
38-
await mutateAsync({
39-
submitterId: userId,
40-
crId,
41-
description,
42-
scopeImpact,
43-
timelineImpact,
44-
budgetImpact
45-
});
39+
try {
40+
// send the details of new proposed solution to the backend database
41+
await mutateAsync({
42+
submitterId: userId,
43+
crId,
44+
description,
45+
scopeImpact,
46+
timelineImpact,
47+
budgetImpact
48+
});
49+
} catch (e) {
50+
if (e instanceof Error) {
51+
toast.error(e.message);
52+
}
53+
}
4654
};
4755

4856
return (

src/frontend/src/pages/CreateChangeRequestPage/CreateChangeRequest.tsx

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,28 +45,34 @@ const CreateChangeRequest: React.FC<CreateChangeRequestProps> = () => {
4545
const { userId } = auth.user;
4646

4747
const handleConfirm = async (data: FormInput) => {
48-
const cr = await mutateAsync({
49-
...data,
50-
wbsNum: validateWBS(wbsNum)
51-
});
52-
const crId = parseInt(cr.message);
53-
proposedSolutions.forEach(async (ps) => {
54-
const { description, timelineImpact, scopeImpact, budgetImpact } = ps;
55-
try {
56-
await cpsMutateAsync({
57-
crId,
58-
submitterId: userId,
59-
description,
60-
timelineImpact,
61-
scopeImpact,
62-
budgetImpact
63-
});
64-
} catch (error: unknown) {
65-
if (error instanceof Error) {
66-
toast.error(error.message);
48+
try {
49+
const cr = await mutateAsync({
50+
...data,
51+
wbsNum: validateWBS(wbsNum)
52+
});
53+
const crId = parseInt(cr.message);
54+
proposedSolutions.forEach(async (ps) => {
55+
const { description, timelineImpact, scopeImpact, budgetImpact } = ps;
56+
try {
57+
await cpsMutateAsync({
58+
crId,
59+
submitterId: userId,
60+
description,
61+
timelineImpact,
62+
scopeImpact,
63+
budgetImpact
64+
});
65+
} catch (error: unknown) {
66+
if (error instanceof Error) {
67+
toast.error(error.message);
68+
}
6769
}
70+
});
71+
} catch (e) {
72+
if (e instanceof Error) {
73+
toast.error(e.message);
6874
}
69-
});
75+
}
7076

7177
history.push(routes.CHANGE_REQUESTS);
7278
};

src/frontend/src/pages/TeamsPage/DescriptionPageBlock.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import ErrorPage from '../ErrorPage';
1414
import PageBlock from '../../layouts/PageBlock';
1515
import ReactMarkdown from 'react-markdown';
1616
import styles from '../../stylesheets/pages/teams.module.css';
17+
import { useToast } from '../../hooks/toasts.hooks';
1718

1819
interface DescriptionPageBlockProps {
1920
team: Team;
@@ -26,6 +27,7 @@ const DescriptionPageBlock: React.FC<DescriptionPageBlockProps> = ({ team }) =>
2627
const [description, setDescription] = useState(team.description);
2728
const [isPreview, setIsPreview] = useState(false);
2829
const { isLoading, isError, error, mutateAsync } = useEditTeamDescription(team.teamId);
30+
const toast = useToast();
2931

3032
if (isError) return <ErrorPage message={error?.message} />;
3133
if (isLoading) return <LoadingIndicator />;
@@ -34,7 +36,14 @@ const DescriptionPageBlock: React.FC<DescriptionPageBlockProps> = ({ team }) =>
3436
if (!isUnderWordCount(description, 300)) {
3537
return alert('Description must be less than 300 words');
3638
}
37-
await mutateAsync(description);
39+
try {
40+
await mutateAsync(description);
41+
} catch (e) {
42+
if (e instanceof Error) {
43+
toast.error(e.message);
44+
}
45+
}
46+
3847
resetDefaults();
3948
};
4049

0 commit comments

Comments
 (0)