diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-07-25 09:14:27 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-07-25 11:55:51 +0200 |
| commit | 8dd2d89f614f1db26196678f86bc86091c5a05d3 (patch) | |
| tree | 32bc125dc6b121e3188d14153603782b10fac924 | |
| parent | d7d89095619d0bc66c2abc8e382c44969ab57bdf (diff) | |
| download | mullvadvpn-8dd2d89f614f1db26196678f86bc86091c5a05d3.tar.xz mullvadvpn-8dd2d89f614f1db26196678f86bc86091c5a05d3.zip | |
Handle error during device removal
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | gui/src/renderer/components/TooManyDevices.tsx | 48 |
2 files changed, 45 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index cdad7440ba..e7716c2ebc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ Line wrap the file at 100 chars. Th - Enable reconnect in blocked state in desktop app. - Fix showing incompatible relay filtering options in desktop app. The filtering options are now dependent on the other filters. +- Fix error handling during device removal in the desktop app. #### Android - Fix unused dependencies loaded in the service/tile DI graph. diff --git a/gui/src/renderer/components/TooManyDevices.tsx b/gui/src/renderer/components/TooManyDevices.tsx index aeed50afd2..f5acffb44c 100644 --- a/gui/src/renderer/components/TooManyDevices.tsx +++ b/gui/src/renderer/components/TooManyDevices.tsx @@ -5,6 +5,7 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; import { IDevice } from '../../shared/daemon-rpc-types'; import { messages } from '../../shared/gettext'; +import log from '../../shared/logging'; import { capitalizeEveryWord } from '../../shared/string-helpers'; import { useAppContext } from '../context'; import { transitions, useHistory } from '../lib/history'; @@ -181,14 +182,41 @@ interface IDeviceProps { } function Device(props: IDeviceProps) { + const { fetchDevices } = useAppContext(); + const accountToken = useSelector((state) => state.account.accountToken)!; const [confirmationVisible, showConfirmation, hideConfirmation] = useBoolean(false); - const [deleting, setDeleting] = useBoolean(false); + const [deleting, setDeleting, unsetDeleting] = useBoolean(false); + const [error, setError, resetError] = useBoolean(false); + + const handleError = useCallback( + async (error: Error) => { + log.error(`Failede to remove device: ${error.message}`); + + let devices: Array<IDevice> | undefined = undefined; + try { + devices = await fetchDevices(accountToken); + } catch { + /* no-op */ + } + + if (devices === undefined || devices.find((device) => device.id === props.device.id)) { + hideConfirmation(); + unsetDeleting(); + setError(); + } + }, + [fetchDevices, accountToken, hideConfirmation, setError], + ); const onRemove = useCallback(async () => { - await props.onRemove(props.device.id); - hideConfirmation(); setDeleting(); - }, [props.onRemove, props.device.id, hideConfirmation, setDeleting]); + try { + await props.onRemove(props.device.id); + hideConfirmation(); + } catch (e) { + await handleError(e as Error); + } + }, [props.onRemove, props.device.id, hideConfirmation, setDeleting, handleError]); const capitalizedDeviceName = capitalizeEveryWord(props.device.name); @@ -262,6 +290,18 @@ function Device(props: IDeviceProps) { </> )} </ModalAlert> + <ModalAlert + isOpen={error} + type={ModalAlertType.warning} + iconColor={colors.red} + buttons={[ + <AppButton.BlueButton key="close" onClick={resetError}> + {messages.gettext('Close')} + </AppButton.BlueButton>, + ]} + close={resetError} + message={messages.pgettext('device-management', 'Failed to remove device')} + /> </> ); } |
