From c980008b70ff0ca0f16336ab6d304c9c9b9a9f59 Mon Sep 17 00:00:00 2001 From: Oleg Lokhvitsky Date: Sun, 23 Jun 2024 23:34:35 -0700 Subject: [PATCH] Lint against floating promises --- .eslintrc.js | 5 +++-- src/main/RequestAPI.ts | 8 ++++--- src/main/main.ts | 8 +++---- src/main/worker/BridgeAPI.ts | 4 ++-- src/main/worker/NetworkFetch.ts | 40 +++++++++++++++++---------------- src/main/worker/UpdaterAPI.ts | 2 +- src/renderer/ModListItem.tsx | 2 +- src/renderer/ModManagerLogs.tsx | 26 +++++++++++---------- src/renderer/ModsContext.tsx | 6 ++--- src/renderer/RunGameButton.tsx | 2 +- src/renderer/UpdaterDialog.tsx | 2 +- 11 files changed, 56 insertions(+), 49 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index afb029c..516eb18 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -18,8 +18,7 @@ module.exports = { 'no-empty': 'off', 'no-inner-declarations': 'off', // customized - 'import/no-unresolved': 'error', - 'react/jsx-boolean-value': ['error', 'always'], + '@typescript-eslint/no-floating-promises': 'error', '@typescript-eslint/no-unused-vars': [ 'warn', { @@ -31,6 +30,8 @@ module.exports = { caughtErrorsIgnorePattern: '^_.*$', }, ], + 'import/no-unresolved': 'error', + 'react/jsx-boolean-value': ['error', 'always'], }, plugins: [ '@typescript-eslint', diff --git a/src/main/RequestAPI.ts b/src/main/RequestAPI.ts index f83fb59..4b67e91 100644 --- a/src/main/RequestAPI.ts +++ b/src/main/RequestAPI.ts @@ -24,15 +24,17 @@ export async function initRequestAPI(): Promise { const onData = (buffer: Buffer) => { // IPC has trouble with Buffer so send it as number[] - BroadcastAPI.send(id, 'data', [...buffer.values()]); + BroadcastAPI.send(id, 'data', [...buffer.values()]).catch( + console.error, + ); }; const onSuccess = () => { - BroadcastAPI.send(id, 'success'); + BroadcastAPI.send(id, 'success').catch(console.error); }; const onFailure = (error: Error) => { - BroadcastAPI.send(id, 'error', error); + BroadcastAPI.send(id, 'error', error).catch(console.error); }; const request = net.request(url); diff --git a/src/main/main.ts b/src/main/main.ts index 34a432b..779da22 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -109,7 +109,7 @@ const createWindow = async () => { // Open urls in the user's browser mainWindow.webContents.on('new-window', (event, url) => { event.preventDefault(); - shell.openExternal(url); + shell.openExternal(url).catch(console.error); }); console.log('[main] Initializing IPC...'); @@ -137,7 +137,7 @@ const createWindow = async () => { app.quit(); } - mainWindow.loadURL(resolveHtmlPath('index.html')); + await mainWindow.loadURL(resolveHtmlPath('index.html')); }; app.on('window-all-closed', () => { @@ -153,11 +153,11 @@ initPreferences(); app .whenReady() .then(() => { - createWindow(); + createWindow().catch(console.error); app.on('activate', () => { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. - if (mainWindow === null) createWindow(); + if (mainWindow === null) createWindow().catch(console.error); }); }) .catch(console.log); diff --git a/src/main/worker/BridgeAPI.ts b/src/main/worker/BridgeAPI.ts index 28291bc..d324a54 100644 --- a/src/main/worker/BridgeAPI.ts +++ b/src/main/worker/BridgeAPI.ts @@ -1026,7 +1026,7 @@ const config = JSON.parse(D2RMM.getConfigJSON()); 'installationProgress', i, runtime.modsToInstall.length, - ); + ).catch(console.error); runtime.mod = runtime.modsToInstall[i]; let code: string = ''; let sourceMap: string = ''; @@ -1105,7 +1105,7 @@ const config = JSON.parse(D2RMM.getConfigJSON()); 'installationProgress', runtime.modsToInstall.length, runtime.modsToInstall.length, - ); + ).catch(console.error); if (!runtime.options.isPreExtractedData) { await BridgeAPI.closeStorage(); diff --git a/src/main/worker/NetworkFetch.ts b/src/main/worker/NetworkFetch.ts index aeb1c22..9de7971 100644 --- a/src/main/worker/NetworkFetch.ts +++ b/src/main/worker/NetworkFetch.ts @@ -37,25 +37,27 @@ export async function fetch( } reject(); }; - RequestAPI.createRequest(sourceUrl).then((id) => { - const listener = async (event: unknown, payload: unknown) => { - switch (event as 'data' | 'success' | 'error') { - case 'data': - onData(payload as number[]); - break; - case 'success': - BroadcastAPI.removeEventListener(id, listener); - onSuccess(); - break; - case 'error': - BroadcastAPI.removeEventListener(id, listener); - onFailure(); - break; - } - }; - BroadcastAPI.addEventListener(id, listener); - RequestAPI.sendRequest(id); - }); + RequestAPI.createRequest(sourceUrl) + .then((id) => { + const listener = async (event: unknown, payload: unknown) => { + switch (event as 'data' | 'success' | 'error') { + case 'data': + onData(payload as number[]); + break; + case 'success': + BroadcastAPI.removeEventListener(id, listener); + onSuccess(); + break; + case 'error': + BroadcastAPI.removeEventListener(id, listener); + onFailure(); + break; + } + }; + BroadcastAPI.addEventListener(id, listener); + RequestAPI.sendRequest(id).catch(console.error); + }) + .catch(console.error); }); } diff --git a/src/main/worker/UpdaterAPI.ts b/src/main/worker/UpdaterAPI.ts index b66c3fc..0dec971 100644 --- a/src/main/worker/UpdaterAPI.ts +++ b/src/main/worker/UpdaterAPI.ts @@ -89,7 +89,7 @@ export async function installUpdate(update: Update): Promise { }); child.unref(); - AppInfoAPI.quit(); + await AppInfoAPI.quit(); } async function cleanupUpdate(): Promise { diff --git a/src/renderer/ModListItem.tsx b/src/renderer/ModListItem.tsx index fb17e8a..527424c 100644 --- a/src/renderer/ModListItem.tsx +++ b/src/renderer/ModListItem.tsx @@ -99,7 +99,7 @@ export default function ModListItem({ const onOpenWebsite = useCallback((): void => { if (mod.info.website != null) { - ShellAPI.openExternal(mod.info.website); + ShellAPI.openExternal(mod.info.website).catch(console.error); } }, [mod]); diff --git a/src/renderer/ModManagerLogs.tsx b/src/renderer/ModManagerLogs.tsx index 48c0510..c9cf6d3 100644 --- a/src/renderer/ModManagerLogs.tsx +++ b/src/renderer/ModManagerLogs.tsx @@ -84,18 +84,20 @@ export default function ModManagerSettings(_props: Props): JSX.Element { ); const onCopy = useCallback((): void => { - navigator.clipboard.writeText( - // always copy all logs, including the filtered ones - // because people will forget to enable debug level - logs - .map((log) => [ - new Date(log.timestamp).toISOString(), - log.level, - ...log.data.map(prettyPrintData), - ]) - .map((log) => log.join(',')) - .join('\n'), - ); + navigator.clipboard + .writeText( + // always copy all logs, including the filtered ones + // because people will forget to enable debug level + logs + .map((log) => [ + new Date(log.timestamp).toISOString(), + log.level, + ...log.data.map(prettyPrintData), + ]) + .map((log) => log.join(',')) + .join('\n'), + ) + .catch(console.error); onCloseExportMenu(); }, [logs, onCloseExportMenu]); diff --git a/src/renderer/ModsContext.tsx b/src/renderer/ModsContext.tsx index 361144d..795f931 100644 --- a/src/renderer/ModsContext.tsx +++ b/src/renderer/ModsContext.tsx @@ -119,7 +119,7 @@ export function ModsContextProvider({ const [mods, setMods] = useState([]); useEffect(() => { - getMods().then(setMods); + getMods().then(setMods).catch(console.error); }, []); const setModConfig = useCallback( @@ -129,7 +129,7 @@ export function ModsContextProvider({ prevMods.map((mod) => { if (mod.id === id) { const config = getConfig(mod.config); - BridgeAPI.writeModConfig(id, config); + BridgeAPI.writeModConfig(id, config).catch(console.error); return { ...mod, config }; } return mod; @@ -141,7 +141,7 @@ export function ModsContextProvider({ const refreshMods = useCallback((): void => { // manually refresh mods - getMods().then(setMods); + getMods().then(setMods).catch(console.error); }, [getMods]); const [installedMods, setInstalledMods] = useSavedState( diff --git a/src/renderer/RunGameButton.tsx b/src/renderer/RunGameButton.tsx index c55f280..cb0b319 100644 --- a/src/renderer/RunGameButton.tsx +++ b/src/renderer/RunGameButton.tsx @@ -22,7 +22,7 @@ export default function RunGameButton(_props: Props): JSX.Element { const command = useMemo(() => ['D2R.exe'].concat(args).join(' '), [args]); const onRunGame = useCallback(() => { - BridgeAPI.execute(`${gamePath}\\D2R.exe`, args); + BridgeAPI.execute(`${gamePath}\\D2R.exe`, args).catch(console.error); }, [args, gamePath]); return ( diff --git a/src/renderer/UpdaterDialog.tsx b/src/renderer/UpdaterDialog.tsx index 2685cf1..5f6c43a 100644 --- a/src/renderer/UpdaterDialog.tsx +++ b/src/renderer/UpdaterDialog.tsx @@ -30,7 +30,7 @@ export default function UpdaterDialog() { const onInstall = useCallback(() => { if (update != null) { - UpdaterAPI.installUpdate(update); + UpdaterAPI.installUpdate(update).catch(console.error); } setIsUpdateIgnored(true); }, [update]);