better api error handling expectations

This commit is contained in:
Michael Fatemi 2021-08-16 22:18:59 -04:00
parent 44bf3001d7
commit 69342ffe8e
23 changed files with 127 additions and 95 deletions

View File

@ -17,7 +17,7 @@ export default function ActiveCarpools() {
const [activeCarpools, setActiveCarpools] = useState<ICarpool[]>([]);
useEffect(() => {
getActiveCarpools().then(setActiveCarpools);
getActiveCarpools().then(setActiveCarpools).catch(console.error); // TODO error handling
}, []);
return (
@ -30,9 +30,11 @@ export default function ActiveCarpools() {
>
<h1 style={{ textAlign: 'center' }}>Carpools</h1>
<UISecondaryBox style={{ width: '100%', boxSizing: 'border-box' }}>
{activeCarpools.length > 0 ? activeCarpools.map((carpool) => (
<ActiveCarpoolListItem carpool={carpool} key={carpool.id} />
)) : "No Carpools"}
{activeCarpools.length > 0
? activeCarpools.map((carpool) => (
<ActiveCarpoolListItem carpool={carpool} key={carpool.id} />
))
: 'No Carpools'}
</UISecondaryBox>
</div>
);

View File

@ -11,7 +11,7 @@ export default function ActiveEvents() {
useEffect(() => {
if (!hasEvents) {
getActiveEvents().then(setEvents);
getActiveEvents().then(setEvents).catch(console.error); // TODO error handling
}
}, [hasEvents, setEvents]);

View File

@ -15,15 +15,19 @@ export default function AuthenticationWrapper({
const sessionToken = localStorage.getItem('session_token');
if (sessionToken) {
const user = await getMe();
if (!('status' in user && user.status === 'error')) {
setUser(user);
return;
try {
setUser(await getMe());
} catch (e) {
console.error(e);
setUser(null);
}
} else {
setUser(null);
}
setUser(null);
}
refresh_().finally(() => setLoaded(true));
refresh_()
.catch(console.error) // TODO error handling
.finally(() => setLoaded(true));
}, []);
useEffect(refresh, [refresh]);

View File

@ -33,6 +33,7 @@ function useToken(
.then(({ token }) => {
setToken(token ?? null);
})
.catch(console.error) // TODO error handling
.finally(() => setPending(false));
}
}, [code, provider]);

View File

@ -58,20 +58,22 @@ export default function Carpool({ id }: { id: number }) {
);
useEffect(() => {
getCarpool(id).then((carpool) => {
const invitationsMap: Record<number, ICarpool['invitations'][0]> = {};
carpool.invitations.forEach((invite) => {
invitationsMap[invite.user.id] = invite;
});
setCarpool({
id: carpool.id,
name: carpool.name,
event: carpool.event,
members: carpool.members,
creatorId: carpool.creatorId,
invitations: invitationsMap,
});
});
getCarpool(id)
.then((carpool) => {
const invitationsMap: Record<number, ICarpool['invitations'][0]> = {};
carpool.invitations.forEach((invite) => {
invitationsMap[invite.user.id] = invite;
});
setCarpool({
id: carpool.id,
name: carpool.name,
event: carpool.event,
members: carpool.members,
creatorId: carpool.creatorId,
invitations: invitationsMap,
});
})
.catch(console.error); // TODO error handling
}, [id, setCarpool]);
const acceptRequest = useCallback(

View File

@ -27,7 +27,7 @@ export default function CarpoolTopButtonsNonMembersOnly() {
const me = useMe() || defaultMe;
const sendRequest = useCallback(() => {
sendCarpoolRequest(carpool.id);
sendCarpoolRequest(carpool.id); // TODO carpool request error handling
}, [carpool.id, sendCarpoolRequest]);
const cancelRequest = useCallback(() => {
@ -35,15 +35,19 @@ export default function CarpoolTopButtonsNonMembersOnly() {
}, [carpool.id, cancelCarpoolRequest]);
const acceptInvitation = useCallback(() => {
acceptCarpoolInvite(carpool.id).then(() => {
members.push(me);
});
acceptCarpoolInvite(carpool.id)
.then(() => {
members.push(me);
})
.catch(console.error); // TODO error handling
}, [acceptCarpoolInvite, carpool.id, members, me]);
const denyInvitation = useCallback(() => {
denyCarpoolInvite(carpool.id).then(() => {
members.push(me);
});
denyCarpoolInvite(carpool.id)
.then(() => {
members.push(me);
})
.catch(console.error); // TODO error handling
}, [carpool.id, denyCarpoolInvite, me, members]);
const invitationState = useInvitationState(carpool.id);

View File

@ -46,7 +46,9 @@ export default function InvitationList() {
useImmutable<PotentialInvitee[] | null>(null);
useEffect(() => {
getPotentialInvitees(carpool.id).then(setAvailableSignups);
getPotentialInvitees(carpool.id)
.then(setAvailableSignups)
.catch(console.error); // TODO error handling
}, [carpool.id, setAvailableSignups]);
const invitedUserIDs = useMemo(

View File

@ -8,9 +8,7 @@ export default function useSignups(eventId: number, userIds: number[]) {
const [signups, setSignups] = useState<IEventSignup[]>([]);
useEffect(() => {
getEventSignupsBulk(eventId, userIds).then((signups) => {
setSignups(signups);
});
getEventSignupsBulk(eventId, userIds).then(setSignups).catch(console.error); // TODO error handling
}, [eventId, userIds]);
return signups;

View File

@ -21,6 +21,7 @@ export default function Event({
setLoading(true);
getEvent(id)
.then((e) => e && setEvent(e))
.catch(console.error) // TODO error handling
.finally(() => setLoading(false));
}, [id, setEvent]);

View File

@ -70,6 +70,7 @@ export default function EventCreator({ group }: { group: IGroup }) {
.then(({ id }) => {
setCreatedEventId(id);
})
.catch(console.error) // TODO error handling
.finally(() => setCreating(false));
}
}, [

View File

@ -30,14 +30,8 @@ export default function Group({ id }: { id: number }) {
useEffect(() => {
setLoading(true);
getGroup(id)
.then((group) => {
// @ts-ignore
if ('status' in group && group.status === 'error') {
setGroup(null);
} else {
setGroup(group);
}
})
.then(setGroup)
.catch(console.error) // TODO error handling
.finally(() => setLoading(false));
}, [id, setGroup]);

View File

@ -19,15 +19,19 @@ export default function GroupInviteCode() {
const [shown, setShown] = useState(false);
const generateJoinCode = useCallback(() => {
generateCode(group.id).then((code) => {
group.joinCode = code;
});
generateCode(group.id)
.then((code) => {
group.joinCode = code;
})
.catch(console.error); // TODO error handling
}, [group]);
const resetJoinCode = useCallback(() => {
resetCode(group.id).then((code) => {
group.joinCode = null;
});
resetCode(group.id)
.then((code) => {
group.joinCode = null;
})
.catch(console.error); // TODO error handling
}, [group]);
if (group.joinCode) {

View File

@ -22,11 +22,13 @@ export default function GroupMembersLink() {
const addAdmin = useCallback(
(adminId: number, adminName: string) => {
addGroupAdmin(group.id, adminId).then(({ status }) => {
if (status === 'success') {
group.admins.push({ id: adminId, name: adminName });
}
});
addGroupAdmin(group.id, adminId)
.then(({ status }) => {
if (status === 'success') {
group.admins.push({ id: adminId, name: adminName });
}
})
.catch(console.error); // TODO error handling
},
[group.admins, group.id]
);
@ -35,11 +37,13 @@ export default function GroupMembersLink() {
const removeAdmin = useCallback(
(adminId: number) => {
removeGroupAdmin(group.id, adminId).then((res) => {
if (res.status === 'success') {
group.admins = group.admins.filter((admin) => admin.id !== adminId);
}
});
removeGroupAdmin(group.id, adminId)
.then((res) => {
if (res.status === 'success') {
group.admins = group.admins.filter((admin) => admin.id !== adminId);
}
})
.catch(console.error); // TODO error handling
},
[group]
);

View File

@ -16,9 +16,7 @@ export default function GroupSettings({ group }: { group: IGroup }) {
.then(({ status }) => {
setDeletionSuccessful(status === 'success');
})
.catch(() => {
setDeletionSuccessful(false);
});
.catch(() => setDeletionSuccessful(false));
}, [group.id]);
const confirmDeletion = useCallback(() => {

View File

@ -19,6 +19,7 @@ export default function GroupCreator() {
setCreationSuccessful(true);
setCreatedGroupId(id);
})
.catch(console.error) // TODO error handling
.finally(() => {
setCreating(false);
});

View File

@ -19,11 +19,13 @@ export function GroupJoiner() {
useEffect(() => {
if (code) {
const initialCode = code;
resolveCode(code).then((group) => {
if (code === initialCode) {
setGroup(group);
}
});
resolveCode(code)
.then((group) => {
if (code === initialCode) {
setGroup(group);
}
})
.catch(console.error);
}
}, [code]);
@ -38,6 +40,7 @@ export function GroupJoiner() {
window.location.href = '/groups/' + id;
}
})
.catch(console.error)
.finally(() => setJoining(false));
}
}, [code, group?.id]);

View File

@ -15,6 +15,7 @@ export default function GroupSharedLinkResolver() {
setResolving(true);
resolveCode(code)
.then(setGroup)
.catch(console.error)
.finally(() => setResolving(false));
}, [code]);
@ -29,6 +30,7 @@ export default function GroupSharedLinkResolver() {
window.location.href = '/groups/' + id;
}
})
.catch(console.error)
.finally(() => setJoining(false));
}
}, [code, group?.id]);

View File

@ -9,7 +9,7 @@ export default function Groups() {
const [groups, setGroups] = useState<IGroup[]>([]);
useEffect(() => {
getGroups().then(setGroups);
getGroups().then(setGroups).catch(console.error); // TODO error handling
}, []);
return (

View File

@ -60,13 +60,15 @@ export default function UIPlacesAutocomplete({
useEffect(() => {
if (placeId) {
getPlaceDetails(placeId).then((result) => {
if (result.formattedAddress.startsWith(result.name)) {
setLocation(result.formattedAddress);
} else {
setLocation(`${result.name}, ${result.formattedAddress}`);
}
});
getPlaceDetails(placeId)
.then((result) => {
if (result.formattedAddress.startsWith(result.name)) {
setLocation(result.formattedAddress);
} else {
setLocation(`${result.name}, ${result.formattedAddress}`);
}
})
.catch(console.error); // TODO error handling
}
}, [placeId]);

View File

@ -23,6 +23,9 @@ async function post(path: string, data: any) {
'Content-Type': 'application/json',
},
});
if (res.status !== 200) {
throw new Error(`${path}: ${await res.text()}`);
}
return await res.json();
}
@ -35,6 +38,9 @@ async function delete$(path: string, body?: any) {
},
body: body ? JSON.stringify(body) : undefined,
});
if (res.status !== 200) {
throw new Error(`${path}: ${await res.text()}`);
}
return await res.json();
}
@ -45,12 +51,10 @@ async function get(path: string) {
},
});
const result = await res.json();
if (res.status !== 200) {
throw new Error(`${path}: ${await res.text()}`);
}
return result;
// if (res.ok) {
// return result;
// } else {
// throw new Error(result.message);
// }
}
export async function getEventSignupsBulk(

View File

@ -10,7 +10,9 @@ export function useNotifications() {
const [notifications, setNotifications] = useState<IInvitation[]>([]);
const refresh = useCallback(() => {
getReceivedInvitationsAndRequests().then(setNotifications);
getReceivedInvitationsAndRequests()
.then(setNotifications)
.catch(console.error); // TODO error handling
}, []);
useEffect(refresh, [refresh]);

View File

@ -9,7 +9,7 @@ export default function usePlace(placeId: string | null) {
if (placeId == null) {
setPlaceDetails(null);
} else {
getPlaceDetails(placeId).then(setPlaceDetails);
getPlaceDetails(placeId).then(setPlaceDetails).catch(console.error); // TODO error handling
}
}, [placeId]);

View File

@ -33,20 +33,23 @@ export default function NotificationsProvider({
>({});
useEffect(() => {
api.getSentRequestsAndInvites().then((invitations) => {
const invited = {} as Record<number, boolean>;
const requested = {} as Record<number, boolean>;
for (let invitation of invitations) {
if (invitation.isRequest) {
invited[invitation.carpool.id] = true;
} else {
requested[invitation.carpool.id] = true;
api
.getSentRequestsAndInvites()
.then((invitations) => {
const invited = {} as Record<number, boolean>;
const requested = {} as Record<number, boolean>;
for (let invitation of invitations) {
if (invitation.isRequest) {
invited[invitation.carpool.id] = true;
} else {
requested[invitation.carpool.id] = true;
}
}
}
setInvitedCarpoolIds(invited);
setRequestedCarpoolIds(requested);
});
setInvitedCarpoolIds(invited);
setRequestedCarpoolIds(requested);
})
.catch(console.error); // TODO error handling
}, [setInvitedCarpoolIds, setRequestedCarpoolIds]);
const sendCarpoolRequest = useCallback(