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

View File

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

View File

@ -15,15 +15,19 @@ export default function AuthenticationWrapper({
const sessionToken = localStorage.getItem('session_token'); const sessionToken = localStorage.getItem('session_token');
if (sessionToken) { if (sessionToken) {
const user = await getMe(); try {
if (!('status' in user && user.status === 'error')) { setUser(await getMe());
setUser(user); } catch (e) {
return; 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]); useEffect(refresh, [refresh]);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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