diff --git a/.eslintrc.json b/.eslintrc.json index 1d69cda83c..cb6ef62b85 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,7 @@ "parserOptions": { "ecmaVersion": 2022 }, - "plugins": ["react", "react-hooks", "simple-import-sort", "sort-destructure-keys"], + "plugins": ["react", "react-hooks", "simple-import-sort", "sort-destructure-keys", "promise"], "rules": { "comma-dangle": "off", "indent": ["error", 4, @@ -55,7 +55,10 @@ "react/prop-types": "off", "react-hooks/exhaustive-deps": "error", - "react-hooks/rules-of-hooks": "error" + "react-hooks/rules-of-hooks": "error", + + "promise/prefer-await-to-then": "error", + "promise/prefer-await-to-callbacks": "error" }, "globals": { "require": false, diff --git a/build.js b/build.js index b97a9b1d0f..8fd79e7226 100755 --- a/build.js +++ b/build.js @@ -33,7 +33,7 @@ function watchDirs (dir, onChange) { } onChange(path.join(dir, fname)); }; - +// eslint-disable-next-line promise/prefer-await-to-callbacks fs.watch(dir, {}, (ev, path) => callback(ev, dir, path)); // watch all subdirectories in dir diff --git a/src/apis/boss.js b/src/apis/boss.js index 536910e258..e84ce492b9 100644 --- a/src/apis/boss.js +++ b/src/apis/boss.js @@ -59,14 +59,14 @@ export class BossClient { * * @returns {Promise} Resolves the total number of tasks */ -export const getSteps = ({ task }) => { - return new BossClient().client.call( +export const getSteps = async ({ task }) => { + const ret = await new BossClient().client.call( task, "org.freedesktop.DBus.Properties", "Get", ["org.fedoraproject.Anaconda.Task", "Steps"] - ) - .then(ret => ret[0]); + ); + return ret[0]; }; /** diff --git a/src/apis/helpers.js b/src/apis/helpers.js index e67ef40e4f..fbe14d3d91 100644 --- a/src/apis/helpers.js +++ b/src/apis/helpers.js @@ -16,20 +16,22 @@ */ import cockpit from "cockpit"; -export const _callClient = (Client, OBJECT_PATH, INTERFACE_NAME, ...args) => { - return new Client().client.call(OBJECT_PATH, INTERFACE_NAME, ...args).then(res => res[0]); +export const _callClient = async (Client, OBJECT_PATH, INTERFACE_NAME, ...args) => { + const res = await new Client().client.call(OBJECT_PATH, INTERFACE_NAME, ...args); + return res[0]; }; -export const _setProperty = (Client, OBJECT_PATH, INTERFACE_NAME, ...args) => { - return new Client().client.call( +export const _setProperty = async (Client, OBJECT_PATH, INTERFACE_NAME, ...args) => { + return await new Client().client.call( OBJECT_PATH, "org.freedesktop.DBus.Properties", "Set", [INTERFACE_NAME, ...args] ); }; -export const _getProperty = (Client, OBJECT_PATH, INTERFACE_NAME, ...args) => { - return new Client().client.call( +export const _getProperty = async (Client, OBJECT_PATH, INTERFACE_NAME, ...args) => { + const res = await new Client().client.call( OBJECT_PATH, "org.freedesktop.DBus.Properties", "Get", [INTERFACE_NAME, ...args] - ).then(res => res[0].v); + ); + return res[0].v; }; /** diff --git a/src/apis/localization.js b/src/apis/localization.js index 8e5da7a6a2..8c801fdb3f 100644 --- a/src/apis/localization.js +++ b/src/apis/localization.js @@ -177,13 +177,25 @@ export const getKeyboardConfiguration = async ({ onFail, onSuccess }) => { }; const addEventListeners = () => { - taskProxy.addEventListener("Stopped", () => taskProxy.Finish().catch(onFail)); + taskProxy.addEventListener("Stopped", async () => { + try { + await taskProxy.Finish(); + } catch (error) { + onFail(error); + } + }); taskProxy.addEventListener("Succeeded", getTaskResult); }; taskProxy.wait(() => { addEventListeners(); - taskProxy.Start().catch(onFail); + (async () => { + try { + await taskProxy.Start(); + } catch (error) { + onFail(error); + } + })(); }); }; diff --git a/src/apis/storage.js b/src/apis/storage.js index c6df51cb0e..61243ca10a 100644 --- a/src/apis/storage.js +++ b/src/apis/storage.js @@ -118,7 +118,13 @@ export const runStorageTask = ({ onFail, onSuccess, task }) => { task ); const addEventListeners = () => { - taskProxy.addEventListener("Stopped", () => taskProxy.Finish().catch(onFail)); + taskProxy.addEventListener("Stopped", async () => { + try { + await taskProxy.Finish(); + } catch (error) { + onFail(error); + } + }); taskProxy.addEventListener("Succeeded", () => { if (succeededEmitted) { return; @@ -129,7 +135,13 @@ export const runStorageTask = ({ onFail, onSuccess, task }) => { }; taskProxy.wait(() => { addEventListeners(); - taskProxy.Start().catch(onFail); + (async () => { + try { + await taskProxy.Start(); + } catch (error) { + onFail(error); + } + })(); }); }; diff --git a/src/apis/storage_partitioning.js b/src/apis/storage_partitioning.js index 07cb5fdb6d..7006713e39 100644 --- a/src/apis/storage_partitioning.js +++ b/src/apis/storage_partitioning.js @@ -69,13 +69,14 @@ export const createPartitioning = ({ method }) => { * * @returns {Promise} The device tree object */ -export const getDeviceTree = ({ partitioning }) => { - return new StorageClient().client.call( +export const getDeviceTree = async ({ partitioning }) => { + const res = await new StorageClient().client.call( partitioning, INTERFACE_NAME_PARTITIONING, "GetDeviceTree", [] - ).then(res => res[0]); + ); + return res[0]; }; /** @@ -94,12 +95,10 @@ export const partitioningSetPassphrase = ({ partitioning, passphrase }) => { * @param {string} partitioning DBus path to a partitioning * @param {boolean} encrypt True if partitions should be encrypted, False otherwise */ -export const partitioningSetEncrypt = ({ encrypt, partitioning }) => { - return getPartitioningRequest({ partitioning }) - .then(request => { - request.encrypted = cockpit.variant("b", encrypt); - return setPartitioningRequest({ partitioning, request }); - }); +export const partitioningSetEncrypt = async ({ encrypt, partitioning }) => { + const request = await getPartitioningRequest({ partitioning }); + request.encrypted = cockpit.variant("b", encrypt); + return setPartitioningRequest({ partitioning, request }); }; /* Create DBus request object for home reuse partitioning @@ -148,19 +147,17 @@ export const partitioningSetHomeReuse = async ({ homeReuseOptions, partitioning /** * @returns {Promise} The request of automatic partitioning */ -export const getPartitioningRequest = ({ partitioning }) => { - return ( - new StorageClient().client.call( - partitioning, - "org.freedesktop.DBus.Properties", - "Get", - [ - INTERFACE_NAME_PARTITIONING_AUTOMATIC, - "Request", - ] - ) - .then(res => res[0].v) +export const getPartitioningRequest = async ({ partitioning }) => { + const res = await new StorageClient().client.call( + partitioning, + "org.freedesktop.DBus.Properties", + "Get", + [ + INTERFACE_NAME_PARTITIONING_AUTOMATIC, + "Request", + ] ); + return res[0].v; }; /** @@ -168,19 +165,17 @@ export const getPartitioningRequest = ({ partitioning }) => { * * @returns {Promise} The partitioning method */ -export const getPartitioningMethod = ({ partitioning }) => { - return ( - new StorageClient().client.call( - partitioning, - "org.freedesktop.DBus.Properties", - "Get", - [ - INTERFACE_NAME_PARTITIONING, - "PartitioningMethod", - ] - ) - .then(res => res[0].v) +export const getPartitioningMethod = async ({ partitioning }) => { + const res = await new StorageClient().client.call( + partitioning, + "org.freedesktop.DBus.Properties", + "Get", + [ + INTERFACE_NAME_PARTITIONING, + "PartitioningMethod", + ] ); + return res[0].v; }; /** @@ -273,13 +268,14 @@ export const setManualPartitioningRequests = ({ partitioning, requests }) => { * * @returns {Promise} The gathered requests for manual partitioning */ -export const gatherRequests = ({ partitioning }) => { - return new StorageClient().client.call( +export const gatherRequests = async ({ partitioning }) => { + const res = await new StorageClient().client.call( partitioning, INTERFACE_NAME_PARTITIONING_MANUAL, "GatherRequests", [] - ).then(res => res[0]); + ); + return res[0]; }; export const applyStorage = async ({ devices, luks, onFail, onSuccess, partitioning }) => { diff --git a/src/components/AnacondaHeader.jsx b/src/components/AnacondaHeader.jsx index 544bcb7667..6b975ece7f 100644 --- a/src/components/AnacondaHeader.jsx +++ b/src/components/AnacondaHeader.jsx @@ -41,10 +41,14 @@ export const AnacondaHeader = ({ currentStepId, dispatch, isFormDisabled, onCrit const isConnected = network.connected; useEffect(() => { - getIsFinal().then( - isFinal => setBeta(!isFinal), - onCritFail({ context: N_("Reading installer version information failed.") }) - ); + (async () => { + try { + const isFinal = await getIsFinal(); + setBeta(!isFinal); + } catch { + onCritFail({ context: N_("Reading installer version information failed.") }); + } + })(); }, [onCritFail]); return ( diff --git a/src/components/Error.jsx b/src/components/Error.jsx index 7255e3a742..874afffb97 100644 --- a/src/components/Error.jsx +++ b/src/components/Error.jsx @@ -117,11 +117,10 @@ export const BZReportModal = ({ // Let's make sure we have the latest logs from journal saved to /tmp/journal.log // Let's not confuse users with syslog // See https://issues.redhat.com/browse/INSTALLER-4210 - cockpit.spawn(["journalctl", "-a"]) - .then((output) => ( - cockpit.file(JOURNAL_LOG) - .replace(output) - )); + (async () => { + const output = await cockpit.spawn(["journalctl", "-a"]); + await cockpit.file(JOURNAL_LOG).replace(output); + })(); }, []); const { diff --git a/src/components/app.jsx b/src/components/app.jsx index de1ef6c0b7..1d65f45717 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -77,10 +77,14 @@ export const Application = ({ conf, dispatch, isFetching, onCritFail, osRelease, // Attach a click event listener to detect external link clicks document.addEventListener("click", allowExternalNavigation); - Promise.all(clients.map(Client => new Client(address, dispatch).init())) - .then(() => { - setStoreInitialized(true); - }, onCritFail({ context: N_("Reading information about the computer failed.") })); + (async () => { + try { + await Promise.all(clients.map(Client => new Client(address, dispatch).init())); + setStoreInitialized(true); + } catch (error) { + onCritFail({ context: N_("Reading information about the computer failed.") })(error); + } + })(); }, [address, dispatch, onCritFail]); // Postpone rendering anything until we read the dbus address and the default configuration @@ -125,7 +129,14 @@ const useConf = ({ onCritFail }) => { const [conf, setConf] = useState(); useEffect(() => { - readConf().then(setConf, onCritFail({ context: N_("Reading installer configuration failed.") })); + (async () => { + try { + const result = await readConf(); + setConf(result); + } catch (error) { + onCritFail({ context: N_("Reading installer configuration failed.") })(error); + } + })(); }, [onCritFail]); return conf; @@ -135,7 +146,14 @@ const useOsRelease = ({ onCritFail }) => { const [osRelease, setOsRelease] = useState(); useEffect(() => { - readOsRelease().then(setOsRelease, onCritFail({ context: N_("Reading information about the OS failed.") })); + (async () => { + try { + const result = await readOsRelease(); + setOsRelease(result); + } catch (error) { + onCritFail({ context: N_("Reading information about the OS failed.") })(error); + } + })(); }, [onCritFail]); return osRelease; @@ -171,7 +189,13 @@ const useAppVersion = () => { const [appVersion, setAppVersion] = useState(initialState); useEffect(() => { - getAnacondaVersion().then(value => setAppVersion(obj => ({ ...obj, backend: value }))); + (async () => { + try { + const value = await getAnacondaVersion(); + setAppVersion(obj => ({ ...obj, backend: value })); + } catch (err) { + } + })(); }, []); return appVersion; }; diff --git a/src/components/installation/InstallationProgress.jsx b/src/components/installation/InstallationProgress.jsx index 90697806dd..3c16f32582 100644 --- a/src/components/installation/InstallationProgress.jsx +++ b/src/components/installation/InstallationProgress.jsx @@ -60,62 +60,77 @@ export const InstallationProgress = ({ onCritFail }) => { const osRelease = useContext(OsReleaseContext); useEffect(() => { - installWithTasks() - .then(tasks => { - const taskProxy = new BossClient().client.proxy( - "org.fedoraproject.Anaconda.Task", - tasks[0] - ); - const categoryProxy = new BossClient().client.proxy( - "org.fedoraproject.Anaconda.TaskCategory", - tasks[0] - ); - - const addEventListeners = () => { - taskProxy.addEventListener("ProgressChanged", (_, step, message) => { - if (step === 0) { - getSteps({ task: tasks[0] }) - .then( - ret => setSteps(ret.v), - onCritFail() - ); + (async () => { + try { + const tasks = await installWithTasks(); + const taskProxy = new BossClient().client.proxy( + "org.fedoraproject.Anaconda.Task", + tasks[0] + ); + const categoryProxy = new BossClient().client.proxy( + "org.fedoraproject.Anaconda.TaskCategory", + tasks[0] + ); + + const addEventListeners = () => { + taskProxy.addEventListener("ProgressChanged", async (_, step, message) => { + if (step === 0) { + try { + const ret = await getSteps({ task: tasks[0] }); + setSteps(ret.v); + } catch (error) { + onCritFail()(error); } - if (message) { - setStatusMessage(message); - refStatusMessage.current = message; - } - }); - taskProxy.addEventListener("Failed", () => { - setStatus("danger"); - }); - taskProxy.addEventListener("Stopped", () => { - taskProxy.Finish().catch(onCritFail({ + } + if (message) { + setStatusMessage(message); + refStatusMessage.current = message; + } + }); + taskProxy.addEventListener("Failed", () => { + setStatus("danger"); + }); + taskProxy.addEventListener("Stopped", async () => { + try { + await taskProxy.Finish(); + } catch (error) { + onCritFail({ context: cockpit.format(N_("Installation of the system failed: $0"), refStatusMessage.current), - })); - }); - categoryProxy.addEventListener("CategoryChanged", (_, category) => { - const step = progressStepsMap[category]; - setCurrentProgressStep(current => { - if (step !== undefined && step >= current) { - return step; - } - return current; - }); - }); - taskProxy.addEventListener("Succeeded", () => { - setStatus("success"); - setCurrentProgressStep(4); + })(error); + } + }); + categoryProxy.addEventListener("CategoryChanged", (_, category) => { + const step = progressStepsMap[category]; + setCurrentProgressStep(current => { + if (step !== undefined && step >= current) { + return step; + } + return current; }); - }; - taskProxy.wait(() => { - addEventListeners(); - taskProxy.Start().catch(onCritFail({ - context: _("Installation of the system failed"), - })); }); - }, onCritFail({ + taskProxy.addEventListener("Succeeded", () => { + setStatus("success"); + setCurrentProgressStep(4); + }); + }; + taskProxy.wait(() => { + addEventListeners(); + (async () => { + try { + await taskProxy.Start(); + } catch (error) { + onCritFail({ + context: _("Installation of the system failed"), + })(error); + } + })(); + }); + } catch (error) { + onCritFail({ context: _("Installation of the system failed"), - })); + })(error); + } + })(); }, [onCritFail]); if (steps === undefined) { diff --git a/src/components/localization/InstallationLanguage.jsx b/src/components/localization/InstallationLanguage.jsx index bbdafb815d..2691cda063 100644 --- a/src/components/localization/InstallationLanguage.jsx +++ b/src/components/localization/InstallationLanguage.jsx @@ -166,37 +166,41 @@ class LanguageSelector extends React.Component { render () { const { languages } = this.props; - const handleOnSelect = (_event, item) => { + const handleOnSelect = async (_event, item) => { for (const languageItem in languages) { for (const localeItem of languages[languageItem].locales) { if (getLocaleId(localeItem) === item) { setLangCookie({ cockpitLang: convertToCockpitLang({ lang: getLocaleId(localeItem) }) }); - setLanguage({ lang: getLocaleId(localeItem) }) - .then(() => setLocale({ locale: getLocaleId(localeItem) })) - .catch(ex => { - this.props.setStepNotification(ex); - }); + try { + await setLanguage({ lang: getLocaleId(localeItem) }); + setLocale({ locale: getLocaleId(localeItem) }); + } catch (ex) { + this.props.setStepNotification(ex); + } this.setState({ lang: item }); - fetch("po.js").then(response => response.text()) - .then(body => { - // always reset old translations - cockpit.locale(null); - // en_US is always null - if (body.trim() === "") { - cockpit.locale({ - "": { - language: "en_US", - "language-direction": "ltr", - } - }); - } else { - // eslint-disable-next-line no-eval - eval(body); + try { + const response = await fetch("po.js"); + const body = await response.text(); + // always reset old translations + cockpit.locale(null); + // en_US is always null + if (body.trim() === "") { + cockpit.locale({ + "": { + language: "en_US", + "language-direction": "ltr", } - - const langEvent = new CustomEvent("cockpit-lang"); - window.dispatchEvent(langEvent); }); + } else { + // eslint-disable-next-line no-eval + eval(body); + } + + const langEvent = new CustomEvent("cockpit-lang"); + window.dispatchEvent(langEvent); + } catch (ex) { + // Silently handle fetch errors + } return; } } diff --git a/src/components/review/Hostname.jsx b/src/components/review/Hostname.jsx index d8ce8f58fa..80c9c3898b 100644 --- a/src/components/review/Hostname.jsx +++ b/src/components/review/Hostname.jsx @@ -54,18 +54,18 @@ const ChangeHostname = ({ initHostname }) => { validateHostname(value); setCurrentHostname(value); }; - const onSubmit = (event) => { - setHostname({ hostname: currentHostname }) - .then(() => { - handleModalToggle(); - }) - .catch(() => { - setError(_("This hostname can't be submitted")); - }); - + const onSubmit = async (event) => { if (event) { event.preventDefault(); } + + try { + await setHostname({ hostname: currentHostname }); + handleModalToggle(); + } catch (error) { + setError(_("This hostname can't be submitted")); + } + return false; }; diff --git a/src/components/storage/cockpit-storage-integration/CheckStorageDialog.jsx b/src/components/storage/cockpit-storage-integration/CheckStorageDialog.jsx index 23fccf43c4..b531c796a6 100644 --- a/src/components/storage/cockpit-storage-integration/CheckStorageDialog.jsx +++ b/src/components/storage/cockpit-storage-integration/CheckStorageDialog.jsx @@ -295,12 +295,15 @@ const unlockDevices = ({ devices, dispatch, onCritFail, onFail, setNextCheckStep debug("luks step started"); - Promise.all(devicesToUnlock.map(unlockDevice)) - .catch(onFail) - .then(() => { - setNextCheckStep(); - dispatch(getDevicesAction()); - }); + (async () => { + try { + await Promise.all(devicesToUnlock.map(unlockDevice)); + setNextCheckStep(); + dispatch(getDevicesAction()); + } catch (error) { + onFail(error); + } + })(); }; const waitForUnlockedDevices = ({ devices, setNextCheckStep }) => { @@ -323,17 +326,26 @@ const scanDevices = ({ dispatch, onFail, setNextCheckStep }) => { // When the dialog is shown rescan to get latest configured storage // and check if we need to prepare manual partitioning - scanDevicesWithTask() - .then(task => { - return runStorageTask({ - onFail, - onSuccess: () => resetPartitioning() - .then(() => dispatch(getDevicesAction())) - .then(setNextCheckStep) - .catch(onFail), - task - }); + (async () => { + try { + const task = await scanDevicesWithTask(); + runStorageTask({ + onFail, + onSuccess: async () => { + try { + await resetPartitioning(); + await dispatch(getDevicesAction()); + setNextCheckStep(); + } catch (error) { + onFail(error); + } + }, + task }); + } catch (error) { + onFail(error); + } + })(); }; const useStorageSetup = ({ dispatch, onCritFail, setError }) => { diff --git a/src/components/storage/installation-method/EncryptedDevices.jsx b/src/components/storage/installation-method/EncryptedDevices.jsx index 3ef8505c44..f48c3cf6dc 100644 --- a/src/components/storage/installation-method/EncryptedDevices.jsx +++ b/src/components/storage/installation-method/EncryptedDevices.jsx @@ -92,52 +92,51 @@ const UnlockDialog = ({ dispatch, lockedLUKSDevices, onClose }) => { const [inProgress, setInProgress] = useState(false); const idPrefix = "unlock-device-dialog"; - const onSubmit = () => { + const onSubmit = async () => { setInProgress(true); - return Promise.allSettled( - lockedLUKSDevices.map(device => ( - unlockDevice({ device, passphrase }) - )) - ).then( - res => { - if (res.every(r => r.status === "fulfilled")) { - if (res.every(r => r.value)) { - // Refresh the list of existing systems after unlocking the devices - findExistingSystems({ - onFail: exc => setDialogWarning(exc.message), - onSuccess: () => { - onClose(); - dispatch(getDevicesAction()); - }, - }); - } else { - const unlockedDevs = res.reduce((acc, r, i) => { - if (r.value) { - acc.push(lockedLUKSDevices[i]); - } - return acc; - }, []); - if (unlockedDevs.length > 0) { - setDialogSuccess(cockpit.format(_("Successfully unlocked $0."), unlockedDevs.join(", "))); - setDialogWarning(undefined); - setPassphrase(""); - } else { - setDialogSuccess(undefined); - setDialogWarning(_("Passphrase did not match any locked device")); + try { + const res = await Promise.allSettled( + lockedLUKSDevices.map(device => ( + unlockDevice({ device, passphrase }) + )) + ); + + if (res.every(r => r.status === "fulfilled")) { + if (res.every(r => r.value)) { + // Refresh the list of existing systems after unlocking the devices + findExistingSystems({ + onFail: exc => setDialogWarning(exc.message), + onSuccess: () => { + onClose(); + dispatch(getDevicesAction()); + }, + }); + } else { + const unlockedDevs = res.reduce((acc, r, i) => { + if (r.value) { + acc.push(lockedLUKSDevices[i]); } - setInProgress(false); + return acc; + }, []); + if (unlockedDevs.length > 0) { + setDialogSuccess(cockpit.format(_("Successfully unlocked $0."), unlockedDevs.join(", "))); + setDialogWarning(undefined); + setPassphrase(""); + } else { + setDialogSuccess(undefined); + setDialogWarning(_("Passphrase did not match any locked device")); } - - // Blivet does not send a signal when a device is unlocked, - // so we need to refresh the device data manually. - dispatch(getDevicesAction()); + setInProgress(false); } - }, - exc => { - setDialogWarning(exc.message); - setInProgress(false); + + // Blivet does not send a signal when a device is unlocked, + // so we need to refresh the device data manually. + dispatch(getDevicesAction()); } - ); + } catch (exc) { + setDialogWarning(exc.message); + setInProgress(false); + } }; return ( diff --git a/src/components/storage/installation-method/InstallationDestination.jsx b/src/components/storage/installation-method/InstallationDestination.jsx index 5c580feb8c..6fd77102c8 100644 --- a/src/components/storage/installation-method/InstallationDestination.jsx +++ b/src/components/storage/installation-method/InstallationDestination.jsx @@ -213,27 +213,34 @@ const LocalDisksSelect = ({ ); }; -const rescanDisks = (setIsRescanningDisks, dispatch, errorHandler) => { +const rescanDisks = async (setIsRescanningDisks, dispatch, errorHandler) => { setIsRescanningDisks(true); - scanDevicesWithTask() - .then(task => { - return runStorageTask({ - onFail: exc => { - setIsRescanningDisks(false); - errorHandler(exc); - }, - onSuccess: () => resetPartitioning() - .then(() => Promise.all([ - dispatch(getDevicesAction()), - dispatch(getDiskSelectionAction()) - ])) - .finally(() => { - setIsRescanningDisks(false); - }) - .catch(errorHandler), - task - }); - }); + try { + const task = await scanDevicesWithTask(); + await runStorageTask({ + onFail: exc => { + setIsRescanningDisks(false); + errorHandler(exc); + }, + onSuccess: async () => { + try { + await resetPartitioning(); + await Promise.all([ + dispatch(getDevicesAction()), + dispatch(getDiskSelectionAction()) + ]); + } catch (exc) { + errorHandler(exc); + } finally { + setIsRescanningDisks(false); + } + }, + task + }); + } catch (exc) { + setIsRescanningDisks(false); + errorHandler(exc); + } }; export const InstallationDestination = ({ diff --git a/src/components/storage/mount-point-mapping/MountPointMapping.jsx b/src/components/storage/mount-point-mapping/MountPointMapping.jsx index af09ca9d78..e132ff3564 100644 --- a/src/components/storage/mount-point-mapping/MountPointMapping.jsx +++ b/src/components/storage/mount-point-mapping/MountPointMapping.jsx @@ -593,14 +593,18 @@ const RequestsTable = ({ setIsFormValid(getRequestsValid(newRequests, deviceData)); /* Sync newRequests to the backend */ - updatePartitioningRequests({ - newRequests, - partitioning: partitioning.path, - requests - }).catch(ex => { - setStepNotification(ex); - setIsFormValid(false); - }); + (async () => { + try { + await updatePartitioningRequests({ + newRequests, + partitioning: partitioning.path, + requests + }); + } catch (ex) { + setStepNotification(ex); + setIsFormValid(false); + } + })(); setUnappliedRequests(newRequests); }, [setIsFormValid, deviceData, unappliedRequests, requests, partitioning.path, setStepNotification]); diff --git a/src/components/users/Accounts.jsx b/src/components/users/Accounts.jsx index 0b2459174b..319ac9e994 100644 --- a/src/components/users/Accounts.jsx +++ b/src/components/users/Accounts.jsx @@ -378,8 +378,9 @@ export const Accounts = ({ const CustomFooter = () => { const accounts = useContext(UsersContext); - const onNext = ({ goToNextStep }) => { - applyAccounts(accounts).then(goToNextStep); + const onNext = async ({ goToNextStep }) => { + await applyAccounts(accounts); + goToNextStep(); }; return ( diff --git a/src/contexts/Common.jsx b/src/contexts/Common.jsx index 3a746e8a29..27eb135c1d 100644 --- a/src/contexts/Common.jsx +++ b/src/contexts/Common.jsx @@ -79,13 +79,15 @@ const SystemInfoContextWrapper = ({ appVersion, children, conf, osRelease }) => const [desktopVariant, setDesktopVariant] = useState(); useEffect(() => { - cockpit.spawn(["ps", "-eo", "comm"]).then(res => { + const detectDesktopVariant = async () => { + const res = await cockpit.spawn(["ps", "-eo", "comm"]); if (res.includes("gnome-shell")) { setDesktopVariant("GNOME"); } else { setDesktopVariant("UNKNOWN"); } - }); + }; + detectDesktopVariant(); }, []); const systemType = conf?.["Installation System"].type; diff --git a/src/helpers/conf.js b/src/helpers/conf.js index fc0ebef653..834a434255 100644 --- a/src/helpers/conf.js +++ b/src/helpers/conf.js @@ -73,9 +73,12 @@ export const parseIni = content => { return dataStore; }; -export const readConf = () => { +export const readConf = async () => { const confFile = cockpit.file(CONF_PATH, { superuser: "try", }); - return confFile.read() - .then(parseIni) - .finally(confFile.close); + try { + const content = await confFile.read(); + return parseIni(content); + } finally { + confFile.close(); + } }; diff --git a/src/helpers/exit.js b/src/helpers/exit.js index 906690beaa..5b163e7bb2 100644 --- a/src/helpers/exit.js +++ b/src/helpers/exit.js @@ -18,15 +18,17 @@ import cockpit from "cockpit"; import { debug, error } from "./log.js"; -export const exitGui = () => { +export const exitGui = async () => { const pidFile = cockpit.file("/run/anaconda/webui_script.pid", { superuser: "try" }); let pid; - pidFile.read() - .then(content => { - pid = content.trim(); - debug("Killing WebUI process, PID: ", pid); - return cockpit.spawn(["kill", pid]); - }) - .catch(exc => error("Failed to kill WebUI process, PID: ", pid, exc.message)) - .finally(pidFile.close); + try { + const content = await pidFile.read(); + pid = content.trim(); + debug("Killing WebUI process, PID: ", pid); + await cockpit.spawn(["kill", pid]); + } catch (exc) { + error("Failed to kill WebUI process, PID: ", pid, exc.message); + } finally { + pidFile.close(); + } }; diff --git a/src/helpers/product.js b/src/helpers/product.js index 2ad1ff992c..a4dc91b340 100644 --- a/src/helpers/product.js +++ b/src/helpers/product.js @@ -18,10 +18,9 @@ import cockpit from "cockpit"; import VERSION from "../../VERSION.txt"; -export const getAnacondaVersion = () => { - return cockpit - .spawn(["anaconda", "--version"]) - .then((content) => content.split(" ").slice(-1)[0].replace("\n", "")); +export const getAnacondaVersion = async () => { + const content = await cockpit.spawn(["anaconda", "--version"]); + return content.split(" ").slice(-1)[0].replace("\n", ""); }; export const getAnacondaUIVersion = () => {