From 54118031a6558d4f93234b3ff9f0ec070f3dfa1e Mon Sep 17 00:00:00 2001 From: Spectralitree <72747870+Spectralitree@users.noreply.github.com> Date: Sun, 3 Oct 2021 19:11:21 +0200 Subject: [PATCH] somewhat better error handling --- src/Components/Private/Edit/EditSystem.js | 18 ++++++-- .../Private/Edit/EditSystemPrivacy.js | 34 +++++++++----- src/Components/Private/MemberCard.js | 46 +++++++++---------- src/Components/Private/MemberPage.js | 44 +++++++++--------- src/Components/Private/System.js | 7 ++- src/Pages/Home.js | 37 +++++++++++---- 6 files changed, 116 insertions(+), 70 deletions(-) diff --git a/src/Components/Private/Edit/EditSystem.js b/src/Components/Private/Edit/EditSystem.js index 4d9c2106..40eea325 100644 --- a/src/Components/Private/Edit/EditSystem.js +++ b/src/Components/Private/Edit/EditSystem.js @@ -16,8 +16,9 @@ const EditSystem = ({ editDesc, setEditMode, setErrorAlert, - setUser, user, + setUser, + setErrorMessage }) => { const [invalidTimezone, setInvalidTimezone] = useState(false); @@ -38,7 +39,11 @@ const EditSystem = ({ Authorization: localStorage.getItem("token"), }, }) - .then((res) => res.json()) + .then((res) => { + if (!res.ok) + throw new Error('HTTP Status ' + res.status) + return res.json(); + }) .then(() => { setUser((prevState) => { return { ...prevState, ...data }; @@ -47,7 +52,14 @@ const EditSystem = ({ setEditMode(false); }) .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); }); }; diff --git a/src/Components/Private/Edit/EditSystemPrivacy.js b/src/Components/Private/Edit/EditSystemPrivacy.js index b7a32e70..27e6c6f1 100644 --- a/src/Components/Private/Edit/EditSystemPrivacy.js +++ b/src/Components/Private/Edit/EditSystemPrivacy.js @@ -10,6 +10,7 @@ const EditSystemPrivacy = ({ setUser, user, setPrivacyEdit, + setErrorMessage }) => { const { register: registerPrivacy, handleSubmit: handleSubmitPrivacy } = useForm(); @@ -24,18 +25,29 @@ const EditSystemPrivacy = ({ Authorization: localStorage.getItem("token"), }, }) - .then((res) => res.json()) - .then((data) => { - setUser((prevState) => { - return { ...prevState, ...data }; - }); - localStorage.setItem("user", JSON.stringify(user)); - setPrivacyEdit(false); - }) - .catch((error) => { - console.error(error); - setErrorAlert(true); + .then((res) => { + if (!res.ok) + throw new Error('HTTP Status ' + res.status) + return res.json(); + }) + .then(() => { + setUser((prevState) => { + return { ...prevState, ...data }; }); + localStorage.setItem("user", JSON.stringify(user)); + setPrivacyEdit(false); + }) + .catch((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); + }); }; return ( diff --git a/src/Components/Private/MemberCard.js b/src/Components/Private/MemberCard.js index 6686c3cb..7272e7c9 100644 --- a/src/Components/Private/MemberCard.js +++ b/src/Components/Private/MemberCard.js @@ -45,6 +45,7 @@ export default function MemberCard(props) { const [ errorAlert, setErrorAlert ] = useState(false); const [ wrongID, setWrongID ] = useState(false); const [ memberDeleted, setMemberDeleted ] = useState(false); + const [ errorMessage, setErrorMessage ] = useState(""); const { 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]); - const submitEdit = data => { - props.edit(Object.assign(member, data)); - + function 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 (res => { + if (!res.ok) { + throw new Error('HTTP Status ' + res.status); + } + return res.json(); + } ).then (data => { setMember(prevState => {return {...prevState, ...data}}); setErrorAlert(false); setEditMode(false); } ).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); }); } + const submitEdit = data => { + props.edit(Object.assign(member, data)); + submitEditPatch(data); + } + const submitPrivacy = data => { props.edit(Object.assign(member, 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); - }) + submitEditPatch(data); } const deleteMember = data => { @@ -232,7 +232,7 @@ export default function MemberCard(props) { function renderCard() { return ( - { errorAlert ? Something went wrong, please try logging in and out again. : "" } + { errorAlert ? {errorMessage} : "" } { editMode ? <> diff --git a/src/Components/Private/MemberPage.js b/src/Components/Private/MemberPage.js index 427f1523..faf9c42e 100644 --- a/src/Components/Private/MemberPage.js +++ b/src/Components/Private/MemberPage.js @@ -45,6 +45,7 @@ export default function MemberPage(props) { const [ errorAlert, setErrorAlert ] = useState(false); const [ wrongID, setWrongID ] = useState(false); const [ memberDeleted, setMemberDeleted ] = useState(false); + const [ errorMessage, setErrorMessage ] = useState(""); const { 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]); - const submitEdit = data => { - props.edit(Object.assign(member, data)); - + function 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 (res => { + if (!res.ok) { + throw new Error('HTTP Status ' + res.status); + } + return res.json(); + } ).then (data => { setMember(prevState => {return {...prevState, ...data}}); setErrorAlert(false); setEditMode(false); } ).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); }); } + const submitEdit = data => { + props.edit(Object.assign(member, data)); + submitEditPatch(data); + } + const submitPrivacy = data => { props.edit(Object.assign(member, 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); - }) + submitEditPatch(data); } const deleteMember = data => { diff --git a/src/Components/Private/System.js b/src/Components/Private/System.js index 83ac9a24..a6059647 100644 --- a/src/Components/Private/System.js +++ b/src/Components/Private/System.js @@ -12,7 +12,7 @@ import { FaAddressCard } from "react-icons/fa"; import EditSystem from "./Edit/EditSystem.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 const match = useRouteMatch("/dash/:memberID"); @@ -35,6 +35,7 @@ export default function System(props) { const [privacyView, setPrivacyView] = 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 useEffect(() => { @@ -126,7 +127,7 @@ export default function System(props) { {errorAlert ? ( - Something went wrong, please try logging in and out again. + {errorMessage} ) : ( "" @@ -143,6 +144,7 @@ export default function System(props) { user={user} setUser={setUser} setEditMode={setEditMode} + setErrorMessage={setErrorMessage} /> ) : ( <> @@ -204,6 +206,7 @@ export default function System(props) { setUser={setUser} user={user} setPrivacyEdit={setPrivacyEdit} + setErrorMessage={setErrorMessage} /> ) : privacyView ? ( <> diff --git a/src/Pages/Home.js b/src/Pages/Home.js index 333339f1..4eb35678 100644 --- a/src/Pages/Home.js +++ b/src/Pages/Home.js @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import * as fetch from 'node-fetch'; @@ -9,8 +9,10 @@ import { FaLockOpen, FaHome } from "react-icons/fa"; import API_URL from "../Constants/constants.js"; -const Home = ({isInvalid, setIsInvalid, isLoading, setIsLoading, isSubmit, setIsSubmit, }) => { -const { register, handleSubmit } = useForm(); +const Home = ({isInvalid, setIsInvalid, isLoading, setIsLoading, isSubmit, setIsSubmit, forceUpdate }) => { + const { register, handleSubmit } = useForm(); + + const [ errorMessage, setErrorMessage ] = useState(""); // submit login form, add the token to the localstorage const onSubmit = (data) => { @@ -32,9 +34,11 @@ const { register, handleSubmit } = useForm(); }, }) // put all the system data in localstorage - // TODO: remove this from localstorage? since we know how to pass stuff along components now - // then push the user to the dash! - .then((res) => res.json()) + .then((res) => { + if (!res.ok) + throw new Error('HTTP Status ' + res.status); + return res.json(); + }) .then((data) => { localStorage.setItem("user", JSON.stringify(data)); setIsSubmit(true); @@ -42,16 +46,27 @@ const { register, handleSubmit } = useForm(); history.push("/dash"); }) // 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) => { console.log(error); setIsInvalid(true); + setErrorMessage(error.message); + if (error.message === "HTTP Status 401") + errorMessage = "Your token is invalid." localStorage.removeItem("token"); localStorage.removeItem("user"); 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 // removing the dependency array causes a rerender loop, so just ignore ESlint here useEffect(() => { @@ -110,7 +125,7 @@ const { register, handleSubmit } = useForm(); {/* if the inserted token is invalid, show invalid error! this also shows if the token used in checkLogIn() is invalid */} {isInvalid ? ( - Invalid token. + {errorMessage} ) : ( "" )} @@ -121,11 +136,15 @@ const { register, handleSubmit } = useForm(); You are logged in already, click here to continue to the dash.

history.push("/dash")} > Continue to dash + logOut()} + >Log out + ) : ( // otherwise, show login form