somewhat better error handling

This commit is contained in:
Spectralitree 2021-10-03 19:11:21 +02:00
parent 884f600d3e
commit 54118031a6
6 changed files with 116 additions and 70 deletions

View File

@ -16,8 +16,9 @@ const EditSystem = ({
editDesc, editDesc,
setEditMode, setEditMode,
setErrorAlert, setErrorAlert,
setUser,
user, user,
setUser,
setErrorMessage
}) => { }) => {
const [invalidTimezone, setInvalidTimezone] = useState(false); const [invalidTimezone, setInvalidTimezone] = useState(false);
@ -38,7 +39,11 @@ const EditSystem = ({
Authorization: localStorage.getItem("token"), Authorization: localStorage.getItem("token"),
}, },
}) })
.then((res) => res.json()) .then((res) => {
if (!res.ok)
throw new Error('HTTP Status ' + res.status)
return res.json();
})
.then(() => { .then(() => {
setUser((prevState) => { setUser((prevState) => {
return { ...prevState, ...data }; return { ...prevState, ...data };
@ -47,7 +52,14 @@ const EditSystem = ({
setEditMode(false); setEditMode(false);
}) })
.catch((error) => { .catch((error) => {
console.error(error); console.log(error);
setErrorMessage(error.message);
if (error.message === 'HTTP Status 401') {
setErrorMessage("Your token is invalid, please log out and enter a new token.")
};
if (error.message === 'HTTP Status 500') {
setErrorMessage("500: Internal server error.")
}
setErrorAlert(true); setErrorAlert(true);
}); });
}; };

View File

@ -10,6 +10,7 @@ const EditSystemPrivacy = ({
setUser, setUser,
user, user,
setPrivacyEdit, setPrivacyEdit,
setErrorMessage
}) => { }) => {
const { register: registerPrivacy, handleSubmit: handleSubmitPrivacy } = const { register: registerPrivacy, handleSubmit: handleSubmitPrivacy } =
useForm(); useForm();
@ -24,8 +25,12 @@ const EditSystemPrivacy = ({
Authorization: localStorage.getItem("token"), Authorization: localStorage.getItem("token"),
}, },
}) })
.then((res) => res.json()) .then((res) => {
.then((data) => { if (!res.ok)
throw new Error('HTTP Status ' + res.status)
return res.json();
})
.then(() => {
setUser((prevState) => { setUser((prevState) => {
return { ...prevState, ...data }; return { ...prevState, ...data };
}); });
@ -33,7 +38,14 @@ const EditSystemPrivacy = ({
setPrivacyEdit(false); setPrivacyEdit(false);
}) })
.catch((error) => { .catch((error) => {
console.error(error); console.log(error);
setErrorMessage(error.message);
if (error.message === 'HTTP Status 401') {
setErrorMessage("Your token is invalid, please log out and enter a new token.")
};
if (error.message === 'HTTP Status 500') {
setErrorMessage("500: Internal server error.")
}
setErrorAlert(true); setErrorAlert(true);
}); });
}; };

View File

@ -45,6 +45,7 @@ export default function MemberCard(props) {
const [ errorAlert, setErrorAlert ] = useState(false); const [ errorAlert, setErrorAlert ] = useState(false);
const [ wrongID, setWrongID ] = useState(false); const [ wrongID, setWrongID ] = useState(false);
const [ memberDeleted, setMemberDeleted ] = useState(false); const [ memberDeleted, setMemberDeleted ] = useState(false);
const [ errorMessage, setErrorMessage ] = useState("");
const { const {
register: registerEdit, register: registerEdit,
@ -122,46 +123,45 @@ export default function MemberCard(props) {
} }
}, [member.description, member.color, member.birthday, member.display_name, member.pronouns, member.avatar_url, member.proxy_tags, member.created, member.banner]); }, [member.description, member.color, member.birthday, member.display_name, member.pronouns, member.avatar_url, member.proxy_tags, member.created, member.banner]);
const submitEdit = data => { function submitEditPatch(data) {
props.edit(Object.assign(member, data));
fetch(`${API_URL}m/${member.id}`,{ fetch(`${API_URL}m/${member.id}`,{
method: 'PATCH', method: 'PATCH',
body: JSON.stringify(data), body: JSON.stringify(data),
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': localStorage.getItem("token") 'Authorization': localStorage.getItem("token")
}}).then (res => res.json() }}).then (res => {
if (!res.ok) {
throw new Error('HTTP Status ' + res.status);
}
return res.json();
}
).then (data => { ).then (data => {
setMember(prevState => {return {...prevState, ...data}}); setMember(prevState => {return {...prevState, ...data}});
setErrorAlert(false); setErrorAlert(false);
setEditMode(false); setEditMode(false);
} }
).catch (error => { ).catch (error => {
console.error(error); console.log(error);
setErrorMessage(error.message);
if (error.message === 'HTTP Status 401') {
setErrorMessage("401: Your token is invalid, please log out and enter a new token.")
};
if (error.message === 'HTTP Status 500') {
setErrorMessage("500: Internal server error.")
}
setErrorAlert(true); setErrorAlert(true);
}); });
} }
const submitEdit = data => {
props.edit(Object.assign(member, data));
submitEditPatch(data);
}
const submitPrivacy = data => { const submitPrivacy = data => {
props.edit(Object.assign(member, data)); props.edit(Object.assign(member, data));
submitEditPatch(data);
fetch(`${API_URL}m/${member.id}`,{
method: 'PATCH',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem("token")
}}).then (res => res.json()
).then (data => {
setMember(prevState => {return {...prevState, ...data}});
setErrorAlert(false);
setprivacyEdit(false)
}
).catch (error => {
console.error(error);
setErrorAlert(true);
})
} }
const deleteMember = data => { const deleteMember = data => {
@ -232,7 +232,7 @@ export default function MemberCard(props) {
function renderCard() { function renderCard() {
return ( return (
<BS.Card.Body style={{borderLeft: `5px solid #${color}` }}> <BS.Card.Body style={{borderLeft: `5px solid #${color}` }}>
{ errorAlert ? <BS.Alert variant="danger">Something went wrong, please try logging in and out again.</BS.Alert> : "" } { errorAlert ? <BS.Alert variant="danger">{errorMessage}</BS.Alert> : "" }
{ editMode ? { editMode ?
<> <>
<BS.Form id='Edit' onSubmit={handleSubmitEdit(submitEdit)}> <BS.Form id='Edit' onSubmit={handleSubmitEdit(submitEdit)}>

View File

@ -45,6 +45,7 @@ export default function MemberPage(props) {
const [ errorAlert, setErrorAlert ] = useState(false); const [ errorAlert, setErrorAlert ] = useState(false);
const [ wrongID, setWrongID ] = useState(false); const [ wrongID, setWrongID ] = useState(false);
const [ memberDeleted, setMemberDeleted ] = useState(false); const [ memberDeleted, setMemberDeleted ] = useState(false);
const [ errorMessage, setErrorMessage ] = useState("");
const { const {
register: registerEdit, register: registerEdit,
@ -123,46 +124,45 @@ export default function MemberPage(props) {
} }
}, [member.description, member.color, member.birthday, member.display_name, member.pronouns, member.avatar_url, member.proxy_tags, member.created, member.banner]); }, [member.description, member.color, member.birthday, member.display_name, member.pronouns, member.avatar_url, member.proxy_tags, member.created, member.banner]);
const submitEdit = data => { function submitEditPatch(data) {
props.edit(Object.assign(member, data));
fetch(`${API_URL}m/${member.id}`,{ fetch(`${API_URL}m/${member.id}`,{
method: 'PATCH', method: 'PATCH',
body: JSON.stringify(data), body: JSON.stringify(data),
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': localStorage.getItem("token") 'Authorization': localStorage.getItem("token")
}}).then (res => res.json() }}).then (res => {
if (!res.ok) {
throw new Error('HTTP Status ' + res.status);
}
return res.json();
}
).then (data => { ).then (data => {
setMember(prevState => {return {...prevState, ...data}}); setMember(prevState => {return {...prevState, ...data}});
setErrorAlert(false); setErrorAlert(false);
setEditMode(false); setEditMode(false);
} }
).catch (error => { ).catch (error => {
console.error(error); console.log(error);
setErrorMessage(error.message);
if (error.message === 'HTTP Status 401') {
setErrorMessage("Your token is invalid, please log out and enter a new token.")
};
if (error.message === 'HTTP Status 500') {
setErrorMessage("500: Internal server error.")
}
setErrorAlert(true); setErrorAlert(true);
}); });
} }
const submitEdit = data => {
props.edit(Object.assign(member, data));
submitEditPatch(data);
}
const submitPrivacy = data => { const submitPrivacy = data => {
props.edit(Object.assign(member, data)); props.edit(Object.assign(member, data));
submitEditPatch(data);
fetch(`${API_URL}m/${member.id}`,{
method: 'PATCH',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem("token")
}}).then (res => res.json()
).then (data => {
setMember(prevState => {return {...prevState, ...data}});
setErrorAlert(false);
setPrivacyMode(false)
}
).catch (error => {
console.error(error);
setErrorAlert(true);
})
} }
const deleteMember = data => { const deleteMember = data => {

View File

@ -12,7 +12,7 @@ import { FaAddressCard } from "react-icons/fa";
import EditSystem from "./Edit/EditSystem.js"; import EditSystem from "./Edit/EditSystem.js";
import EditSystemPrivacy from "./Edit/EditSystemPrivacy.js"; import EditSystemPrivacy from "./Edit/EditSystemPrivacy.js";
export default function System(props) { export default function System() {
// match the url, if there's a member ID there, don't render this component at all // match the url, if there's a member ID there, don't render this component at all
const match = useRouteMatch("/dash/:memberID"); const match = useRouteMatch("/dash/:memberID");
@ -35,6 +35,7 @@ export default function System(props) {
const [privacyView, setPrivacyView] = useState(false); const [privacyView, setPrivacyView] = useState(false);
const [errorAlert, setErrorAlert] = useState(false); const [errorAlert, setErrorAlert] = useState(false);
const [ errorMessage, setErrorMessage ] = useState("");
// this useEffect does a couple of things after the user is gotten from localstorage // this useEffect does a couple of things after the user is gotten from localstorage
useEffect(() => { useEffect(() => {
@ -126,7 +127,7 @@ export default function System(props) {
<BS.Card.Body> <BS.Card.Body>
{errorAlert ? ( {errorAlert ? (
<BS.Alert variant="danger"> <BS.Alert variant="danger">
Something went wrong, please try logging in and out again. {errorMessage}
</BS.Alert> </BS.Alert>
) : ( ) : (
"" ""
@ -143,6 +144,7 @@ export default function System(props) {
user={user} user={user}
setUser={setUser} setUser={setUser}
setEditMode={setEditMode} setEditMode={setEditMode}
setErrorMessage={setErrorMessage}
/> />
) : ( ) : (
<> <>
@ -204,6 +206,7 @@ export default function System(props) {
setUser={setUser} setUser={setUser}
user={user} user={user}
setPrivacyEdit={setPrivacyEdit} setPrivacyEdit={setPrivacyEdit}
setErrorMessage={setErrorMessage}
/> />
) : privacyView ? ( ) : privacyView ? (
<> <>

View File

@ -1,4 +1,4 @@
import React, { useEffect } from "react"; import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import * as fetch from 'node-fetch'; import * as fetch from 'node-fetch';
@ -9,8 +9,10 @@ import { FaLockOpen, FaHome } from "react-icons/fa";
import API_URL from "../Constants/constants.js"; import API_URL from "../Constants/constants.js";
const Home = ({isInvalid, setIsInvalid, isLoading, setIsLoading, isSubmit, setIsSubmit, }) => { const Home = ({isInvalid, setIsInvalid, isLoading, setIsLoading, isSubmit, setIsSubmit, forceUpdate }) => {
const { register, handleSubmit } = useForm(); const { register, handleSubmit } = useForm();
const [ errorMessage, setErrorMessage ] = useState("");
// submit login form, add the token to the localstorage // submit login form, add the token to the localstorage
const onSubmit = (data) => { const onSubmit = (data) => {
@ -32,9 +34,11 @@ const { register, handleSubmit } = useForm();
}, },
}) })
// put all the system data in localstorage // put all the system data in localstorage
// TODO: remove this from localstorage? since we know how to pass stuff along components now .then((res) => {
// then push the user to the dash! if (!res.ok)
.then((res) => res.json()) throw new Error('HTTP Status ' + res.status);
return res.json();
})
.then((data) => { .then((data) => {
localStorage.setItem("user", JSON.stringify(data)); localStorage.setItem("user", JSON.stringify(data));
setIsSubmit(true); setIsSubmit(true);
@ -42,16 +46,27 @@ const { register, handleSubmit } = useForm();
history.push("/dash"); history.push("/dash");
}) })
// remove the token and user data from localstorage if there's an error, also set the token as invalid // remove the token and user data from localstorage if there's an error, also set the token as invalid
// TODO: an error doesn't mean the token is invalid, change this depending on what error is thrown
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
setIsInvalid(true); setIsInvalid(true);
setErrorMessage(error.message);
if (error.message === "HTTP Status 401")
errorMessage = "Your token is invalid."
localStorage.removeItem("token"); localStorage.removeItem("token");
localStorage.removeItem("user"); localStorage.removeItem("user");
setIsLoading(false); setIsLoading(false);
}); });
} }
// Logout function
function logOut() {
setIsSubmit(false);
localStorage.removeItem("token");
localStorage.removeItem("user");
history.push("/");
forceUpdate();
};
// when the homepage loads, check if there's a token, if there is, check if it's still valid // when the homepage loads, check if there's a token, if there is, check if it's still valid
// removing the dependency array causes a rerender loop, so just ignore ESlint here // removing the dependency array causes a rerender loop, so just ignore ESlint here
useEffect(() => { useEffect(() => {
@ -110,7 +125,7 @@ const { register, handleSubmit } = useForm();
{/* if the inserted token is invalid, show invalid error! {/* if the inserted token is invalid, show invalid error!
this also shows if the token used in checkLogIn() is invalid */} this also shows if the token used in checkLogIn() is invalid */}
{isInvalid ? ( {isInvalid ? (
<BS.Alert variant="danger">Invalid token.</BS.Alert> <BS.Alert variant="danger">{errorMessage}</BS.Alert>
) : ( ) : (
"" ""
)} )}
@ -121,11 +136,15 @@ const { register, handleSubmit } = useForm();
You are logged in already, click here to continue to the dash. You are logged in already, click here to continue to the dash.
</p> </p>
<BS.Button <BS.Button
type="primary" variant="primary"
onClick={() => history.push("/dash")} onClick={() => history.push("/dash")}
> >
Continue to dash Continue to dash
</BS.Button> </BS.Button>
<BS.Button style={{float: 'right'}} variant="danger"
onClick={() => logOut()}
>Log out
</BS.Button>
</> </>
) : ( ) : (
// otherwise, show login form // otherwise, show login form