Skip to content

Commit e63dd88

Browse files
authored
Merge pull request #1421 from Northeastern-Electric-Racing/#1250-try-catch-all-mutate-async
#1250: Try Catch and Toast uncaught Mutate Async
2 parents bee2bb3 + 1355112 commit e63dd88

8 files changed

Lines changed: 72 additions & 30 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/pages/ChangeRequestDetailPage/ProposedSolutionsList.tsx

Lines changed: 17 additions & 10 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} />;
@@ -33,16 +35,21 @@ const ProposedSolutionsList: React.FC<ProposedSolutionsListProps> = ({ proposedS
3335
const addProposedSolution = async (data: ProposedSolution) => {
3436
setShowEditableForm(false);
3537
const { description, timelineImpact, scopeImpact, budgetImpact } = data;
36-
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-
});
38+
try {
39+
// send the details of new proposed solution to the backend database
40+
await mutateAsync({
41+
submitterId: userId,
42+
crId,
43+
description,
44+
scopeImpact,
45+
timelineImpact,
46+
budgetImpact
47+
});
48+
} catch (e) {
49+
if (e instanceof Error) {
50+
toast.error(e.message);
51+
}
52+
}
4653
};
4754

4855
return (

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

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,15 @@ 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 {
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+
5657
await cpsMutateAsync({
5758
crId,
5859
submitterId: userId,
@@ -61,14 +62,14 @@ const CreateChangeRequest: React.FC<CreateChangeRequestProps> = () => {
6162
scopeImpact,
6263
budgetImpact
6364
});
64-
} catch (error: unknown) {
65-
if (error instanceof Error) {
66-
toast.error(error.message);
67-
}
68-
}
69-
});
65+
});
7066

71-
history.push(routes.CHANGE_REQUESTS);
67+
history.push(routes.CHANGE_REQUESTS);
68+
} catch (e) {
69+
if (e instanceof Error) {
70+
toast.error(e.message);
71+
}
72+
}
7273
};
7374

7475
const handleCancel = () => {

src/frontend/src/pages/FinancePage/EditReimbursementRequest/EditReimbursementRequest.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ const EditReimbursementRequestPage: React.FC = () => {
2828

2929
const onSubmit = async (data: ReimbursementRequestDataSubmission): Promise<string> => {
3030
const filesToKeep = data.receiptFiles.filter((file) => file.googleFileId !== '');
31+
3132
await editReimbursementRequest({ ...data, receiptPictures: filesToKeep });
3233
await uploadReceipts({
3334
id: reimbursementRequest.reimbursementRequestId,
3435
files: data.receiptFiles.filter((receipt) => receipt.googleFileId === '').map((file) => file.file!)
3536
});
37+
3638
return reimbursementRequest.reimbursementRequestId;
3739
};
3840

src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/SubmitToSaboModal.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import ErrorPage from '../../ErrorPage';
88
import { datePipe } from '../../../utils/pipes';
99
import DetailDisplay from '../../../components/DetailDisplay';
1010
import { imagePreviewUrl } from '../../../utils/reimbursement-request.utils';
11+
import { useToast } from '../../../hooks/toasts.hooks';
1112

1213
interface SubmitToSaboModalProps {
1314
open: boolean;
@@ -21,6 +22,7 @@ const SubmitToSaboModal = ({ open, setOpen, reimbursementRequest }: SubmitToSabo
2122
const { recipient, dateOfExpense, totalCost, vendor, expenseType, reimbursementProducts, receiptPictures } =
2223
reimbursementRequest;
2324
const { data: userInfo, isLoading, isError, error } = useUserSecureSettings(recipient.userId);
25+
const toast = useToast();
2426

2527
if (!user.isFinance) return <></>;
2628
if (isLoading || !userInfo) return <LoadingIndicator />;
@@ -33,7 +35,14 @@ const SubmitToSaboModal = ({ open, setOpen, reimbursementRequest }: SubmitToSabo
3335
.join(', ');
3436

3537
const handleSubmitToSabo = () => {
36-
submitToSabo();
38+
try {
39+
submitToSabo();
40+
} catch (e) {
41+
if (e instanceof Error) {
42+
toast.error(e.message);
43+
}
44+
}
45+
3746
setOpen(false);
3847
};
3948

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

src/frontend/src/tests/components/CheckList.test.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as descBulletHooks from '../../hooks/description-bullets.hooks';
1111
import { mockAuth } from '../test-support/test-data/test-utils.stub';
1212
import { exampleAdminUser } from '../test-support/test-data/users.stub';
1313
import { mockCheckDescBulletReturnValue } from '../test-support/mock-hooks';
14+
import { ToastProvider } from '../../components/Toast/ToastProvider';
1415

1516
const testItems: CheckListItem[] = [
1617
{ id: 1, detail: 'testItem1', resolved: false },
@@ -24,7 +25,9 @@ const renderComponent = (items: CheckListItem[] = [], title: string = '', isDisa
2425
const RouterWrapper = routerWrapperBuilder({});
2526
return render(
2627
<RouterWrapper>
27-
<CheckList items={items} title={title} isDisabled={isDisabled} />
28+
<ToastProvider>
29+
<CheckList items={items} title={title} isDisabled={isDisabled} />{' '}
30+
</ToastProvider>
2831
</RouterWrapper>
2932
);
3033
};

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ProposedSolution } from 'shared';
99
import { exampleAdminUser, exampleLeadershipUser } from '../../test-support/test-data/users.stub';
1010
import * as authHooks from '../../../hooks/auth.hooks';
1111
import { mockAuth } from '../../test-support/test-data/test-utils.stub';
12+
import { ToastProvider } from '../../../components/Toast/ToastProvider';
1213

1314
const exampleProposedSolution1: ProposedSolution = {
1415
id: '1',
@@ -41,7 +42,9 @@ const renderComponent = (proposedSolutions: ProposedSolution[] = [], crReviewed:
4142
const RouterWrapper = routerWrapperBuilder({});
4243
return render(
4344
<RouterWrapper>
44-
<ProposedSolutionsList proposedSolutions={proposedSolutions} crReviewed={crReviewed} crId={0} />
45+
<ToastProvider>
46+
<ProposedSolutionsList proposedSolutions={proposedSolutions} crReviewed={crReviewed} crId={0} />{' '}
47+
</ToastProvider>
4548
</RouterWrapper>
4649
);
4750
};

0 commit comments

Comments
 (0)