Centralise generic API error handling
authorAdam Dullage <redacted>
Tue, 7 May 2024 19:59:30 +0000 (20:59 +0100)
committerAdam Dullage <redacted>
Tue, 7 May 2024 19:59:30 +0000 (20:59 +0100)
client/App.vue
client/api.js
client/helpers.js
client/views/Home.vue
client/views/LogIn.vue
client/views/Note.vue
client/views/SearchResults.vue

index 66c290ecdd06edc9d3dee6e6ceaebe45d12fd5db..4591effdbcb5265242c5031ee5ca8466917f3f90 100644 (file)
@@ -18,10 +18,10 @@ import { useToast } from "primevue/usetoast";
 import { computed, ref } from "vue";\r
 import { RouterView, useRoute } from "vue-router";\r
 \r
-import { getConfig } from "./api.js";\r
+import { getConfig, apiErrorHandler } from "./api.js";\r
 import PrimeToast from "./components/PrimeToast.vue";\r
 import { useGlobalStore } from "./globalStore.js";\r
-import { getUnknownServerErrorToastOptions, loadTheme } from "./helpers.js";\r
+import { loadTheme } from "./helpers.js";\r
 import NavBar from "./partials/NavBar.vue";\r
 import SearchModal from "./partials/SearchModal.vue";\r
 import { loadStoredToken } from "./tokenStorage.js";\r
@@ -42,9 +42,10 @@ getConfig()
   .then((data) => {\r
     globalStore.authType = data.authType;\r
   })\r
-  .catch(() => {\r
-    toast.add(getUnknownServerErrorToastOptions());\r
+  .catch((error) => {\r
+    apiErrorHandler(error, toast);\r
   });\r
+\r
 loadStoredToken();\r
 \r
 const showNavBar = computed(() => {\r
index da86ccdd14f87dec15b30c51421fa04ad4c0dd65..a6a6707373dbebd228fc2d7eec70bce1c9965573 100644 (file)
@@ -4,6 +4,7 @@ import { Note, SearchResult } from "./classes.js";
 
 import axios from "axios";
 import { getStoredToken } from "./tokenStorage.js";
+import { getToastOptions } from "./helpers.js";
 import router from "./router.js";
 
 const api = axios.create();
@@ -22,25 +23,43 @@ api.interceptors.request.use(
   },
 );
 
-api.interceptors.response.use(
-  function (response) {
-    return response;
-  },
-  function (error) {
-    // If the response is a 401 Unauthorized, redirect to the login page.
-    if (
-      error.response?.status === 401 &&
-      router.currentRoute.value.name !== "login"
-    ) {
-      const redirectPath = router.currentRoute.value.fullPath;
-      router.push({
-        name: "login",
-        query: { [constants.params.redirect]: redirectPath },
-      });
-    }
-    return Promise.reject(error);
-  },
-);
+// api.interceptors.response.use(
+//   function (response) {
+//     return response;
+//   },
+//   function (error) {
+//     // If the response is a 401 Unauthorized, redirect to the login page.
+//     if (
+//       error.response?.status === 401 &&
+//       router.currentRoute.value.name !== "login"
+//     ) {
+//       const redirectPath = router.currentRoute.value.fullPath;
+//       router.push({
+//         name: "login",
+//         query: { [constants.params.redirect]: redirectPath },
+//       });
+//     }
+//     return Promise.reject(error);
+//   },
+// );
+
+export function apiErrorHandler(error, toast) {
+  if (error.response?.status === 401) {
+    const redirectPath = router.currentRoute.value.fullPath;
+    router.push({
+      name: "login",
+      query: { [constants.params.redirect]: redirectPath },
+    });
+  } else {
+    toast.add(
+      getToastOptions(
+        "Unknown Error",
+        "Unknown error communicating with the server. Please try again.",
+        true,
+      ),
+    );
+  }
+}
 
 export async function getConfig() {
   try {
index 290796b296f4e344d1f8dae4d048e457385aa295..a144ba08620c0f75ad5064446610d32d763cef41 100644 (file)
@@ -8,14 +8,6 @@ export function getToastOptions(title, description, isFailure = false) {
   };
 }
 
-export function getUnknownServerErrorToastOptions() {
-  return getToastOptions(
-    "Unknown Error",
-    "Unknown error communicating with the server. Please try again.",
-    true,
-  );
-}
-
 export function setDarkThemeOn(save = true) {
   document.body.classList.add("dark");
   if (save) localStorage.setItem("darkTheme", "true");
index 8857db2b6adbdcaf7e454f9172bc35e90b5ad820..c94e2c7cdd46387bf85b8a7530f0af815e202029 100644 (file)
@@ -23,10 +23,9 @@ import { useToast } from "primevue/usetoast";
 import { ref } from "vue";
 import { RouterLink } from "vue-router";
 
-import { getNotes } from "../api.js";
+import { getNotes, apiErrorHandler } from "../api.js";
 import CustomButton from "../components/CustomButton.vue";
 import Logo from "../components/Logo.vue";
-import { getUnknownServerErrorToastOptions } from "../helpers.js";
 import SearchInput from "../partials/SearchInput.vue";
 
 const notes = ref([]);
@@ -37,6 +36,6 @@ getNotes("*", "lastModified", "desc", 5)
     notes.value = data;
   })
   .catch((error) => {
-    toast.add(getUnknownServerErrorToastOptions(error));
+    apiErrorHandler(error, toast);
   });
 </script>
index 05a99131483d3f4998773e706dfe052c8b9e7d91..339c1529e039a45a6e9301ef128dd38620ac2469 100644 (file)
@@ -45,17 +45,14 @@ import { ref } from "vue";
 import { useRouter, useRoute } from "vue-router";
 import { useToast } from "primevue/usetoast";
 
-import { getToken } from "../api.js";
+import { getToken, apiErrorHandler } from "../api.js";
 import CustomButton from "../components/CustomButton.vue";
 import Logo from "../components/Logo.vue";
 import TextInput from "../components/TextInput.vue";
 import { authTypes } from "../constants.js";
 import { useGlobalStore } from "../globalStore.js";
 import { storeToken } from "../tokenStorage.js";
-import {
-  getToastOptions,
-  getUnknownServerErrorToastOptions,
-} from "../helpers.js";
+import { getToastOptions } from "../helpers.js";
 
 const props = defineProps({ redirect: String });
 
@@ -78,12 +75,12 @@ function logIn() {
         router.push({ name: "home" });
       }
     })
-    .catch((response) => {
+    .catch((error) => {
       username.value = "";
       password.value = "";
       totp.value = "";
 
-      if (response.response?.status === 401) {
+      if (error.response?.status === 401) {
         toast.add(
           getToastOptions(
             "Login Failed",
@@ -92,7 +89,7 @@ function logIn() {
           ),
         );
       } else {
-        toast.add(getUnknownServerErrorToastOptions());
+        apiErrorHandler(error, toast);
       }
     });
 }
index 0ba885fb79cb0e75cff17ec5673a9d5981a01e80..c3ccb75c20a760703a267b6247fa954e5b18d911 100644 (file)
@@ -79,17 +79,20 @@ import { useToast } from "primevue/usetoast";
 import { computed, onMounted, ref, watch } from "vue";
 import { useRouter } from "vue-router";
 
-import { createNote, deleteNote, getNote, updateNote } from "../api.js";
+import {
+  createNote,
+  deleteNote,
+  getNote,
+  updateNote,
+  apiErrorHandler,
+} from "../api.js";
 import { Note } from "../classes.js";
 import ConfirmModal from "../components/ConfirmModal.vue";
 import CustomButton from "../components/CustomButton.vue";
 import LoadingIndicator from "../components/LoadingIndicator.vue";
 import ToastEditor from "../components/toastui/ToastEditor.vue";
 import ToastViewer from "../components/toastui/ToastViewer.vue";
-import {
-  getToastOptions,
-  getUnknownServerErrorToastOptions,
-} from "../helpers.js";
+import { getToastOptions } from "../helpers.js";
 
 const props = defineProps({
   title: String,
@@ -126,11 +129,11 @@ function init() {
         loadingIndicator.value.setLoaded();
       })
       .catch((error) => {
-        if (error.response.status === 404) {
+        if (error.response?.status === 404) {
           loadingIndicator.value.setFailed("Note not found", mdiNoteOffOutline);
         } else {
           loadingIndicator.value.setFailed();
-          toast.add(getUnknownServerErrorToastOptions());
+          apiErrorHandler(error, toast);
         }
       });
   } else {
@@ -155,8 +158,8 @@ function deleteConfirmedHandler() {
     .then(() => {
       router.push({ name: "home" });
     })
-    .catch(() => {
-      toast.add(getUnknownServerErrorToastOptions());
+    .catch((error) => {
+      apiErrorHandler(error, toast);
     });
 }
 
@@ -214,7 +217,7 @@ function noteSaveFailure(error) {
       ),
     );
   } else {
-    toast.add(getUnknownServerErrorToastOptions());
+    apiErrorHandler(error, toast);
   }
 }
 
index 68e948f85fc6d22c1c27793f5853a649e916e192..f30ea1cf8e2ccb0ec3aa6cdf3e6b80b507542289 100644 (file)
@@ -43,7 +43,6 @@ import { mdiMagnify } from "@mdi/js";
 import { getNotes } from "../api.js";
 import LoadingIndicator from "../components/LoadingIndicator.vue";
 import Tag from "../components/Tag.vue";
-import { getUnknownServerErrorToastOptions } from "../helpers.js";
 import SearchInput from "../partials/SearchInput.vue";
 
 const props = defineProps({ searchTerm: String });
@@ -63,9 +62,9 @@ function init() {
         loadingIndicator.value.setFailed("No Results", mdiMagnify);
       }
     })
-    .catch(() => {
+    .catch((error) => {
       loadingIndicator.value.setFailed();
-      toast.add(getUnknownServerErrorToastOptions());
+      apiErrorHandler(error, toast);
     });
 }
 
git clone https://git.99rst.org/PROJECT