diff --git a/src/components/ExtensionCard.tsx b/src/components/ExtensionCard.tsx index 20bae09f..01e2d40c 100644 --- a/src/components/ExtensionCard.tsx +++ b/src/components/ExtensionCard.tsx @@ -16,6 +16,7 @@ import { Box } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { PartialExtension, TranslationKey } from '@/typings'; import { requestManager } from '@/lib/requests/RequestManager.ts'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; interface IProps { extension: PartialExtension; @@ -108,10 +109,14 @@ export function ExtensionCard(props: IProps) { case ExtensionAction.INSTALL: case ExtensionAction.UPDATE: case ExtensionAction.UNINSTALL: - requestExtensionAction(installedState).catch(() => {}); + requestExtensionAction(installedState).catch( + defaultPromiseErrorHandler(`ExtensionCard:handleButtonClick(${installedState})`), + ); break; case ExtensionState.OBSOLETE: - requestExtensionAction(ExtensionAction.UNINSTALL).catch(() => {}); + requestExtensionAction(ExtensionAction.UNINSTALL).catch( + defaultPromiseErrorHandler(`ExtensionCard:handleButtonClick(${installedState})`), + ); break; default: break; diff --git a/src/components/library/UpdateChecker.tsx b/src/components/library/UpdateChecker.tsx index edb8c2d8..a6955d1c 100644 --- a/src/components/library/UpdateChecker.tsx +++ b/src/components/library/UpdateChecker.tsx @@ -15,6 +15,7 @@ import { requestManager } from '@/lib/requests/RequestManager.ts'; import { makeToast } from '@/components/util/Toast'; import { UpdaterSubscription } from '@/lib/graphql/generated/graphql.ts'; import { Progress } from '@/components/util/Progress'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; const calcProgress = (status: UpdaterSubscription['updateStatusChanged'] | undefined) => { if (!status) { @@ -64,14 +65,14 @@ export function UpdateChecker({ handleFinishedUpdate }: { handleFinishedUpdate?: lastRunningState = false; handleFinishedUpdate?.(); // this re-fetch is necessary since a running update could have been triggered by the server or another client - reFetchLastTimestamp().catch(() => {}); + reFetchLastTimestamp().catch(defaultPromiseErrorHandler('UpdateChecker::reFetchLastTimestamp')); }, [status?.isRunning]); const onClick = async () => { try { lastRunningState = true; await requestManager.startGlobalUpdate().response; - reFetchLastTimestamp().catch(() => {}); + reFetchLastTimestamp().catch(defaultPromiseErrorHandler('UpdateChecker::reFetchLastTimestamp')); } catch (e) { lastRunningState = false; makeToast(t('global.error.label.update_failed'), 'error'); diff --git a/src/components/manga/MangaActionMenuItems.tsx b/src/components/manga/MangaActionMenuItems.tsx index 201faecd..cb7c0939 100644 --- a/src/components/manga/MangaActionMenuItems.tsx +++ b/src/components/manga/MangaActionMenuItems.tsx @@ -21,6 +21,7 @@ import { SelectableCollectionReturnType } from '@/components/collection/useSelec import { CategorySelect } from '@/components/navbar/action/CategorySelect.tsx'; import { MenuItem } from '@/components/menu/MenuItem.tsx'; import { createGetMenuItemTitle, createIsMenuItemDisabled, createShouldShowMenuItem } from '@/components/menu/util.ts'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; const ACTION_DISABLES_SELECTION_MODE: MangaAction[] = ['remove_from_library'] as const; @@ -63,7 +64,7 @@ export const MangaActionMenuItems = ({ manga, handleSelection, selectedMangas = const performAction = (action: MangaAction, mangas: TManga[]) => { Mangas.performAction(action, manga ? [manga.id] : Mangas.getIds(mangas), { wasManuallyMarkedAsRead: true, - }).catch(() => {}); + }).catch(defaultPromiseErrorHandler(`MangaActionMenuItems:performAction(${action})`)); onClose(!ACTION_DISABLES_SELECTION_MODE.includes(action)); }; diff --git a/src/components/settings/ServerUpdateChecker.tsx b/src/components/settings/ServerUpdateChecker.tsx index e5c4a0d6..e5b78c48 100644 --- a/src/components/settings/ServerUpdateChecker.tsx +++ b/src/components/settings/ServerUpdateChecker.tsx @@ -17,6 +17,7 @@ import { useTranslation } from 'react-i18next'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { getVersion } from '@/screens/settings/About.tsx'; import { useLocalStorage } from '@/util/useLocalStorage.tsx'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; const UPDATE_CHECK_INTERVAL = 1000 * 60 * 60 * 24; // 1 day @@ -54,7 +55,7 @@ export const ServerUpdateChecker = () => { let timeout: NodeJS.Timeout | undefined; const scheduleUpdateCheck = (timeoutMS: number) => { timeout = setTimeout(() => { - checkForUpdate().catch(() => {}); + checkForUpdate().catch(defaultPromiseErrorHandler('ServerUpdateChecker::checkForUpdate')); setLastUpdateCheck(Date.now()); scheduleUpdateCheck(UPDATE_CHECK_INTERVAL); }, timeoutMS); diff --git a/src/lib/requests/RequestManager.ts b/src/lib/requests/RequestManager.ts index c68858fc..ed7fc7f2 100644 --- a/src/lib/requests/RequestManager.ts +++ b/src/lib/requests/RequestManager.ts @@ -238,6 +238,7 @@ import { CLEAR_SERVER_CACHE } from '@/lib/graphql/mutations/ImageMutation.ts'; import { RESET_WEBUI_UPDATE_STATUS, UPDATE_WEBUI } from '@/lib/graphql/mutations/ServerInfoMutation.ts'; import { WEBUI_UPDATE_SUBSCRIPTION } from '@/lib/graphql/subscriptions/ServerInfoSubscription.ts'; import { GET_DOWNLOAD_STATUS } from '@/lib/graphql/queries/DownloaderQuery.ts'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; enum GQLMethod { QUERY = 'QUERY', @@ -514,7 +515,7 @@ export class RequestManager { await revalidationPromise; setActiveRevalidation(null); } catch (e) { - // ignore + defaultPromiseErrorHandler(`RequestManager..revalidatePages(${getVariablesFor(0)})`)(e); } finally { setValidating(false); } diff --git a/src/screens/DownloadQueue.tsx b/src/screens/DownloadQueue.tsx index abd3051b..fbc07787 100644 --- a/src/screens/DownloadQueue.tsx +++ b/src/screens/DownloadQueue.tsx @@ -29,6 +29,7 @@ import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts'; import { TChapter } from '@/typings.ts'; import { NavBarContext } from '@/components/context/NavbarContext.tsx'; import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; const HeightPreservingItem = ({ children, ...props }: BoxProps) => ( // the height is necessary to prevent the item container from collapsing, which confuses Virtuoso measurements @@ -203,7 +204,7 @@ export const DownloadQueue: React.FC = () => { return; } - requestManager.startDownloads().response.catch(() => {}); + requestManager.startDownloads().response.catch(defaultPromiseErrorHandler('DownloadQueue::startDownloads')); }; if (isLoading) { diff --git a/src/screens/Reader.tsx b/src/screens/Reader.tsx index 5409c849..184cd18e 100644 --- a/src/screens/Reader.tsx +++ b/src/screens/Reader.tsx @@ -30,6 +30,7 @@ import { NavBarContext } from '@/components/context/NavbarContext.tsx'; import { useDebounce } from '@/util/useDebounce.ts'; import { UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts'; import { useMetadataServerSettings } from '@/util/metadataServerSettings.ts'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; const isDupChapter = async (chapterIndex: number, currentChapter: TChapter) => { const nextChapter = await requestManager.getChapter(currentChapter.manga.id, chapterIndex).response; @@ -209,7 +210,7 @@ export function Reader() { chapterIdToDelete: getChapterIdToDelete(), downloadAheadMangaId: shouldDownloadAhead ? chapter.manga.id : undefined, }) - .response.catch(() => {}); + .response.catch(); }; const setSettingValue = (key: keyof IReaderSettings, value: string | boolean) => { @@ -264,7 +265,9 @@ export function Reader() { useEffect(() => { if (!areDefaultSettingsLoading && !isMangaLoading) { - checkAndHandleMissingStoredReaderSettings(manga, 'manga', defaultSettings).catch(() => {}); + checkAndHandleMissingStoredReaderSettings(manga, 'manga', defaultSettings).catch( + defaultPromiseErrorHandler('Reader::checkAndHandleMissingStoredReaderSettings'), + ); setSettings(getReaderSettingsFor(manga, defaultSettings)); } }, [areDefaultSettingsLoading, isMangaLoading]); diff --git a/src/screens/settings/About.tsx b/src/screens/settings/About.tsx index 950b55db..1ad16842 100644 --- a/src/screens/settings/About.tsx +++ b/src/screens/settings/About.tsx @@ -25,6 +25,7 @@ import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder'; import { GetAboutQuery, UpdateState } from '@/lib/graphql/generated/graphql.ts'; import { ABOUT_WEBUI, WEBUI_UPDATE_CHECK } from '@/lib/graphql/Fragments.ts'; import { makeToast } from '@/components/util/Toast.tsx'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; type AboutServer = GetAboutQuery['aboutServer']; @@ -224,7 +225,9 @@ export function About() { const resetUpdateStatus = isError || updateFinished; if (resetUpdateStatus) { - requestManager.resetWebUIUpdateStatus().response.catch(() => {}); + requestManager + .resetWebUIUpdateStatus() + .response.catch(defaultPromiseErrorHandler('About::resetWebUIUpdateStatus')); } if (!updateFinished) { @@ -326,7 +329,11 @@ export function About() { isUpdateAvailable={isWebUIUpdateAvailable} updateCheckError={webUIUpdateCheckError} checkForUpdate={checkForWebUIUpdate} - triggerUpdate={() => requestManager.updateWebUI().response.catch(() => {})} + triggerUpdate={() => + requestManager + .updateWebUI() + .response.catch(defaultPromiseErrorHandler('About::updateWebUI')) + } progress={webUIUpdateProgress} updateState={webUIUpdateState} /> diff --git a/src/screens/settings/DefaultReaderSettings.tsx b/src/screens/settings/DefaultReaderSettings.tsx index 88cad0c3..9abce787 100644 --- a/src/screens/settings/DefaultReaderSettings.tsx +++ b/src/screens/settings/DefaultReaderSettings.tsx @@ -20,6 +20,7 @@ import { import { ReaderSettingsOptions } from '@/components/reader/ReaderSettingsOptions'; import { makeToast } from '@/components/util/Toast'; import { NavBarContext, useSetDefaultBackTo } from '@/components/context/NavbarContext'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; export function DefaultReaderSettings() { const { t } = useTranslation(); @@ -58,7 +59,7 @@ export function DefaultReaderSettings() { { meta: convertToGqlMeta(metadata)! }, 'server', getDefaultSettings(), - ).catch(() => {}); + ).catch(defaultPromiseErrorHandler('DefaultReaderSettings::checkAndHandleMissingStoredReaderSettings')); return ( (error: any) => + console.error(`${name} failed due to`, error);