From 72868d85748b760140dd76bc0c316867e313037e Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Mon, 24 May 2021 14:49:59 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20better=20error=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nest_frontend/App.js | 5 +- nest_frontend/LocalizationStrings.js | 4 ++ .../components/base/{BoxAlert.js => Alert.js} | 4 +- .../{BoxAlert.module.css => Alert.module.css} | 0 .../components/base/formparts/FormAlert.js | 8 ++-- .../components/boundaries/ErrorBoundary.js | 27 +++++++++++ .../components/interactive/AlertError.js | 47 +++++++++++++++++++ nest_frontend/objects/MapArea.test.js | 1 + nest_frontend/routes/PageShare.js | 6 +-- nest_frontend/routes/PageUsers.js | 4 +- nest_frontend/utils/renderContents.js | 4 +- 11 files changed, 96 insertions(+), 14 deletions(-) rename nest_frontend/components/base/{BoxAlert.js => Alert.js} (81%) rename nest_frontend/components/base/{BoxAlert.module.css => Alert.module.css} (100%) create mode 100644 nest_frontend/components/boundaries/ErrorBoundary.js create mode 100644 nest_frontend/components/interactive/AlertError.js diff --git a/nest_frontend/App.js b/nest_frontend/App.js index 3101014..ab7ff26 100644 --- a/nest_frontend/App.js +++ b/nest_frontend/App.js @@ -6,6 +6,7 @@ import GlobalServer from "./components/providers/GlobalServer" import GlobalUser from "./components/providers/GlobalUser" import PageSwitcher from "./PageSwitcher" import GlobalLanguage from "./components/providers/GlobalLanguage" +import ErrorBoundary from "./components/boundaries/ErrorBoundary" /** @@ -22,7 +23,9 @@ export default function App() { - + + + diff --git a/nest_frontend/LocalizationStrings.js b/nest_frontend/LocalizationStrings.js index b1fa75f..b75200a 100644 --- a/nest_frontend/LocalizationStrings.js +++ b/nest_frontend/LocalizationStrings.js @@ -138,6 +138,10 @@ export default { errorAlertNoWindow: "Errore: Finestra di allarme non specificata.", errorAlertNoEvaluation: "Errore: Modalità di valutazione non specificata.", errorAlertDeletionFailure: "Errore: Qualcosa sta impedendo l'eliminazione dell'allarme.", + errorViewNotAllowed: "Errore: Non è permesso effettuare la richiesta.", // TODO: Tradurre + errorServerNotConfigured: "Errore: Non è stato configurato nessun server.", // TODO: Tradurre + errorDecodeError: "Errore: Non è stato possibile deserializzare i dati ricevuti dal backend.", // TODO: Tradurre + errorSerializationError: "Errore: Non è stato possibile serializzare i dati da inviare al backend." // TODO: Tradurre }, // 🇬🇧 en: { diff --git a/nest_frontend/components/base/BoxAlert.js b/nest_frontend/components/base/Alert.js similarity index 81% rename from nest_frontend/components/base/BoxAlert.js rename to nest_frontend/components/base/Alert.js index 829b28a..b510a8e 100644 --- a/nest_frontend/components/base/BoxAlert.js +++ b/nest_frontend/components/base/Alert.js @@ -1,5 +1,5 @@ import React from "react" -import Style from "./BoxAlert.module.css" +import Style from "./Alert.module.css" import classNames from "classnames" @@ -13,7 +13,7 @@ import classNames from "classnames" * @returns {JSX.Element} * @constructor */ -export default function BoxAlert({ color, children, className, ...props }) { +export default function Alert({ color, children, className, ...props }) { return (
{children} diff --git a/nest_frontend/components/base/BoxAlert.module.css b/nest_frontend/components/base/Alert.module.css similarity index 100% rename from nest_frontend/components/base/BoxAlert.module.css rename to nest_frontend/components/base/Alert.module.css diff --git a/nest_frontend/components/base/formparts/FormAlert.js b/nest_frontend/components/base/formparts/FormAlert.js index f30a707..c1d7297 100644 --- a/nest_frontend/components/base/formparts/FormAlert.js +++ b/nest_frontend/components/base/formparts/FormAlert.js @@ -1,11 +1,11 @@ import React from "react" import Style from "./FormAlert.module.css" import classNames from "classnames" -import BoxAlert from "../BoxAlert" +import Alert from "../Alert" /** - * A {@link BoxAlert} ready to be used in a {@link FormLabelled}. + * A {@link Alert} ready to be used in a {@link FormLabelled}. * * @param children - The contents of the alert. * @param className - Additional class(es) to add to the box. @@ -15,8 +15,8 @@ import BoxAlert from "../BoxAlert" */ export default function FormAlert({ children, className, ...props }) { return ( - + {children} - + ) } diff --git a/nest_frontend/components/boundaries/ErrorBoundary.js b/nest_frontend/components/boundaries/ErrorBoundary.js new file mode 100644 index 0000000..2048f65 --- /dev/null +++ b/nest_frontend/components/boundaries/ErrorBoundary.js @@ -0,0 +1,27 @@ +import React from "react" +import AlertError from "../interactive/AlertError" + + +export default class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = {error: null} + } + + static getDerivedStateFromError(error) { + // I'm not too sure on what this does + return {error} + } + + componentDidCatch(error, errorInfo) { + console.error("Caught error ", error, " with info ", errorInfo) + this.setState(state => state.error = error) + } + + render() { + if(this.state.error) { + return + } + return this.props.children + } +} diff --git a/nest_frontend/components/interactive/AlertError.js b/nest_frontend/components/interactive/AlertError.js new file mode 100644 index 0000000..4d04ae9 --- /dev/null +++ b/nest_frontend/components/interactive/AlertError.js @@ -0,0 +1,47 @@ +import React, { useMemo } from "react" +import Alert from "../base/Alert" +import {FontAwesomeIcon} from "@fortawesome/react-fontawesome" +import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons" +import { + DecodeError, + ResultError, + SerializationError, + ServerNotConfiguredError, + ViewNotAllowedError, +} from "../../objects/Errors" +import useStrings from "../../hooks/useStrings" + + +export default function AlertError({ error, ...props }) { + const strings = useStrings() + + const content = useMemo( + () => { + if(error instanceof ViewNotAllowedError) { + return strings.errorViewNotAllowed + } + else if(error instanceof ServerNotConfiguredError) { + return strings.errorServerNotConfigured + } + else if(error instanceof DecodeError) { + return strings.errorDecodeError + } + else if(error instanceof ResultError) { + return strings[error.getCode()] + } + else if(error instanceof SerializationError) { + return strings.errorSerializationError + } + else { + return error.toString() + } + }, + [strings, error] + ) + + return ( + + {content} + + ) +} diff --git a/nest_frontend/objects/MapArea.test.js b/nest_frontend/objects/MapArea.test.js index cf64005..03e50c0 100644 --- a/nest_frontend/objects/MapArea.test.js +++ b/nest_frontend/objects/MapArea.test.js @@ -11,3 +11,4 @@ test("MapArea can be rendered to a spec-compatible string", () => { const mapArea = new MapArea(1000, new Coordinates(0.0, 0.0)) expect(mapArea.toString()).toBe("< 1000 0.0000000 0.0000000") }) + diff --git a/nest_frontend/routes/PageShare.js b/nest_frontend/routes/PageShare.js index 8b4e0f2..2067461 100644 --- a/nest_frontend/routes/PageShare.js +++ b/nest_frontend/routes/PageShare.js @@ -7,7 +7,7 @@ import BoxUserList from "../components/interactive/BoxUserList" import useBackendViewset from "../hooks/useBackendViewset" import { useParams } from "react-router" import ContextUser from "../contexts/ContextUser" -import BoxAlert from "../components/base/BoxAlert" +import Alert from "../components/base/Alert" import useStrings from "../hooks/useStrings" @@ -90,10 +90,10 @@ export default function PageShare({ className, ...props }) { running={usersBvRunning && authBvRunning} /> {authBvError ? - {strings[authBvError?.data?.code ?? "errorUnknownError"]} + {strings[authBvError?.data?.code ?? "errorUnknownError"]} : null} {usersBvError ? - {strings[usersBvError?.data?.code ?? "errorUnknownError"]} + {strings[usersBvError?.data?.code ?? "errorUnknownError"]} : null}
) diff --git a/nest_frontend/routes/PageUsers.js b/nest_frontend/routes/PageUsers.js index 5d9da5f..e216cef 100644 --- a/nest_frontend/routes/PageUsers.js +++ b/nest_frontend/routes/PageUsers.js @@ -6,7 +6,7 @@ import BoxUserCreate from "../components/interactive/BoxUserCreate" import useBackendViewset from "../hooks/useBackendViewset" import BoxUserList from "../components/interactive/BoxUserList" import ContextLanguage from "../contexts/ContextLanguage" -import BoxAlert from "../components/base/BoxAlert" +import Alert from "../components/base/Alert" export default function PageUsers({ children, className, ...props }) { @@ -22,7 +22,7 @@ export default function PageUsers({ children, className, ...props }) { {bv.error ? - {strings[bv.error?.data?.code ?? "errorUnknownError"]} + {strings[bv.error?.data?.code ?? "errorUnknownError"]} : null} ) diff --git a/nest_frontend/utils/renderContents.js b/nest_frontend/utils/renderContents.js index d84965a..f1ea761 100644 --- a/nest_frontend/utils/renderContents.js +++ b/nest_frontend/utils/renderContents.js @@ -1,6 +1,6 @@ import React from "react" import Loading from "../components/base/Loading" -import BoxAlert from "../components/base/BoxAlert" +import Alert from "../components/base/Alert" import Starting from "../components/base/Starting" @@ -11,7 +11,7 @@ export default function renderContents(requestHookResults, renderFunction) { return } if(error) { - return {error.toString()} + return {error.toString()} } if(data) { return renderFunction(data)