From ae54fd20dde29b285ef091cfc08c8b92b670e181 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Mon, 30 Mar 2026 20:08:34 -0400 Subject: [PATCH] feat(frontend): integrate error handling into application App.svelte: - Import and render ErrorModal component - Add ErrorModal to main app layout below Header CheckIfAniListLoggedInAndLoadWatchList.svelte: - Import error state helpers (setApiError, clearApiError) - Wrap LoadAniListUser in try-catch with error handling - Wrap LoadAniListWatchList in try-catch with error handling - Update CheckIfAniListLoggedInAndLoadWatchList with error handling - Remove old alert() calls in favor of modal system Home.svelte: - Import isApiDown and apiError stores - Add conditional rendering for API down state - Display user-friendly "API Unavailable" message when apiError is set - Show warning icon and helpful messaging Error handling is now fully integrated across the frontend application. --- frontend/src/App.svelte | 2 + ...ckIfAniListLoggedInAndLoadWatchList.svelte | 60 +++++++++++++++---- frontend/src/routes/Home.svelte | 58 +++++++++++++----- 3 files changed, 93 insertions(+), 27 deletions(-) diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 29c8234..264b96b 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -25,6 +25,7 @@ SimklGetUserWatchlist, } from "../wailsjs/go/main/App"; import { loc } from "svelte-spa-router"; + import ErrorModal from "./helperComponents/ErrorModal.svelte"; onMount(async () => { let isAniListLoggedIn: boolean; @@ -57,6 +58,7 @@
+ (sort = value)); export const LoadAniListUser = async () => { - await GetAniListLoggedInUser().then((user) => { - aniListUser.set(user); - }); + try { + await GetAniListLoggedInUser().then((user) => { + aniListUser.set(user); + }); + } catch (err) { + const errorMsg = err instanceof Error ? err.message : String(err); + setApiError( + "anilist", + `Failed to load user: ${errorMsg}`, + undefined, + true, + ); + throw err; + } }; export const LoadAniListWatchList = async () => { - await GetAniListUserWatchingList(page, perPage, sort).then((watchList) => { + try { + const watchList = await GetAniListUserWatchingList(page, perPage, sort); aniListWatchlist.set(watchList); - }); - }; - - export const CheckIfAniListLoggedInAndLoadWatchList = async () => { - const loggedIn = await CheckIfAniListLoggedIn(); - if (loggedIn) { - await LoadAniListUser(); - if (isAniListPrimary) await LoadAniListWatchList(); + clearApiError(); + } catch (err) { + const errorMsg = err instanceof Error ? err.message : String(err); + setApiError( + "anilist", + `Failed to load watch list: ${errorMsg}`, + undefined, + true, + ); + throw err; + } + }; + export const CheckIfAniListLoggedInAndLoadWatchList = async () => { + try { + const loggedIn = await CheckIfAniListLoggedIn(); + if (loggedIn) { + await LoadAniListUser(); + if (isAniListPrimary) await LoadAniListWatchList(); + } + aniListLoggedIn.set(loggedIn); + } catch (err) { + const errorMsg = err instanceof Error ? err.message : String(err); + setApiError( + "anilist", + `Authentication failed: ${errorMsg}`, + undefined, + true, + ); + aniListLoggedIn.set(false); } - aniListLoggedIn.set(loggedIn); }; diff --git a/frontend/src/routes/Home.svelte b/frontend/src/routes/Home.svelte index 25c523f..ca4c0b3 100644 --- a/frontend/src/routes/Home.svelte +++ b/frontend/src/routes/Home.svelte @@ -1,25 +1,55 @@ -{#if isAniListLoggedIn && isAniListPrimary} -
+ +{#if $isApiDown} +
+
+ + + +

+ API Unavailable +

+

+ The {$apiError?.service || "service"} is currently unavailable. The app will + remain open, and you can retry when the service is back online. +

+
+
+{:else if isAniListLoggedIn && isAniListPrimary} +
-
+
{:else} -
-{/if} \ No newline at end of file +
+{/if}