From c94849d3a1f24f77a4b91939653ba8a3c607d988 Mon Sep 17 00:00:00 2001 From: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com> Date: Mon, 24 Mar 2025 10:19:02 -0700 Subject: [PATCH] Improve error messaging for startup database error --- _locales/en/messages.json | 12 ++++++-- app/main.ts | 49 +++++++++++++++++++++++---------- images/app-icon-with-error.png | Bin 0 -> 13373 bytes ts/util/getAppErrorIcon.ts | 17 ++++++++++++ 4 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 images/app-icon-with-error.png create mode 100644 ts/util/getAppErrorIcon.ts diff --git a/_locales/en/messages.json b/_locales/en/messages.json index a65852ea83..6f97885a95 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -111,6 +111,14 @@ "messageformat": "Unknown group", "description": "Shown as the name of a group if we don't have any information about it" }, + "icu:cantOpenSignalError": { + "messageformat": "Can’t Open Signal", + "description": "Title of a popup if the app cannot start up properly" + }, + "icu:cantOpenSignalError__detail": { + "messageformat": "To help fix the issue, follow the recovery guide on the support page or contact Signal support to help fix the issue.\n\nIf you need to use Signal right away, you can delete your data and relink this desktop. You will have the option to transfer message history from your phone.", + "description": "Description shown in a popup if the app cannot start up properly" + }, "icu:databaseError": { "messageformat": "Database Error", "description": "Title of a popup if the database cannot start up properly" @@ -124,11 +132,11 @@ "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" }, "icu:databaseError__deleteDataConfirmation": { - "messageformat": "Permanently delete all data?", + "messageformat": "Permanently Delete All Data", "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" }, "icu:databaseError__deleteDataConfirmation__detail": { - "messageformat": "All of your message history and media will be permanently deleted from this device. You will be able to use Signal on this device after relinking it. This will not delete any data from your phone.", + "messageformat": "All of your message history and media will be permanently deleted from this device. This will not delete any data from your phone.\n\nYou will be able to use Signal on this device after relinking it. You will have the option to transfer message history from your phone.", "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" }, "icu:databaseError__startOldVersion": { diff --git a/app/main.ts b/app/main.ts index 0ba2e7ced2..c04038a639 100644 --- a/app/main.ts +++ b/app/main.ts @@ -123,6 +123,7 @@ import { SafeStorageBackendChangeError } from '../ts/types/SafeStorageBackendCha import { LINUX_PASSWORD_STORE_FLAGS } from '../ts/util/linuxPasswordStoreFlags'; import { getOwn } from '../ts/util/getOwn'; import { safeParseLoose, safeParseUnknown } from '../ts/util/schemas'; +import { getAppErrorIcon } from '../ts/util/getAppErrorIcon'; const animationSettings = systemPreferences.getAnimationSettings(); @@ -1814,12 +1815,14 @@ const onDatabaseError = async (error: Error) => { const { i18n } = getResolvedMessagesLocale(); + let copyErrorAndQuitButtonIndex: number; let deleteAllDataButtonIndex: number | undefined; + let goToSupportPageButtonIndex: number | undefined; + let defaultButtonId: number; + let messageTitle: string; let messageDetail: string; - const buttons = [i18n('icu:copyErrorAndQuit')]; - const copyErrorAndQuitButtonIndex = 0; - const SIGNAL_SUPPORT_LINK = 'https://support.signal.org/error'; + const buttons = []; // Note that this error is thrown by the worker process and thus instanceof // check won't work. @@ -1827,13 +1830,18 @@ const onDatabaseError = async (error: Error) => { // If the DB version is too new, the user likely opened an older version of Signal, // and they would almost never want to delete their data as a result, so we don't show // that option + messageTitle = i18n('icu:databaseError'); messageDetail = i18n('icu:databaseError__startOldVersion'); + buttons.push(i18n('icu:copyErrorAndQuit')); + copyErrorAndQuitButtonIndex = 0; + defaultButtonId = copyErrorAndQuitButtonIndex; } else if (error instanceof SafeStorageBackendChangeError) { const { currentBackend, previousBackend } = error; const previousBackendFlag = getOwn( LINUX_PASSWORD_STORE_FLAGS, previousBackend ); + messageTitle = i18n('icu:databaseError'); messageDetail = previousBackendFlag ? i18n('icu:databaseError__safeStorageBackendChangeWithPreviousFlag', { currentBackend, @@ -1844,27 +1852,32 @@ const onDatabaseError = async (error: Error) => { currentBackend, previousBackend, }); + buttons.push(i18n('icu:copyErrorAndQuit')); + copyErrorAndQuitButtonIndex = 0; + defaultButtonId = copyErrorAndQuitButtonIndex; } else { - // Otherwise, this is some other kind of DB error, let's give them the option to - // delete. - messageDetail = i18n( - 'icu:databaseError__detail', - { link: SIGNAL_SUPPORT_LINK }, - { bidi: 'strip' } - ); - + // Otherwise, this is some other kind of DB error, most likely broken safeStorage key. + // Let's give them the option to delete and show them the support guide. + messageTitle = i18n('icu:cantOpenSignalError'); + messageDetail = i18n('icu:cantOpenSignalError__detail'); + buttons.push(i18n('icu:goToSupportPage')); + goToSupportPageButtonIndex = 0; + // Delete button should be the hardest to click buttons.push(i18n('icu:deleteAndRestart')); deleteAllDataButtonIndex = 1; + buttons.push(i18n('icu:copyErrorAndQuit')); + copyErrorAndQuitButtonIndex = 2; + defaultButtonId = goToSupportPageButtonIndex; } const buttonIndex = dialog.showMessageBoxSync({ buttons, - defaultId: copyErrorAndQuitButtonIndex, + defaultId: defaultButtonId, cancelId: copyErrorAndQuitButtonIndex, - message: i18n('icu:databaseError'), + message: messageTitle, detail: messageDetail, + icon: getAppErrorIcon(), noLink: true, - type: 'error', }); if (buttonIndex === copyErrorAndQuitButtonIndex) { @@ -1889,8 +1902,8 @@ const onDatabaseError = async (error: Error) => { cancelId: cancelButtonIndex, message: i18n('icu:databaseError__deleteDataConfirmation'), detail: i18n('icu:databaseError__deleteDataConfirmation__detail'), + icon: getAppErrorIcon(), noLink: true, - type: 'warning', }); if (confirmationButtonIndex === confirmDeleteAllDataButtonIndex) { @@ -1902,6 +1915,12 @@ const onDatabaseError = async (error: Error) => { ); app.relaunch(); } + } else if (buttonIndex === goToSupportPageButtonIndex) { + drop( + shell.openExternal( + 'https://support.signal.org/hc/articles/9045714156314-Can-t-Open-Signal-Desktop' + ) + ); } getLogger().error('onDatabaseError: Quitting application'); diff --git a/images/app-icon-with-error.png b/images/app-icon-with-error.png new file mode 100644 index 0000000000000000000000000000000000000000..f73082a79c30880408f996d5f68b9de556a1f578 GIT binary patch literal 13373 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 TVC^2s00000NkvXXu0mjfMNXzd literal 0 HcmV?d00001 diff --git a/ts/util/getAppErrorIcon.ts b/ts/util/getAppErrorIcon.ts new file mode 100644 index 0000000000..41187f4d6e --- /dev/null +++ b/ts/util/getAppErrorIcon.ts @@ -0,0 +1,17 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import { nativeImage } from 'electron'; +import type { NativeImage } from 'electron'; +import { join } from 'path'; + +export function getAppErrorIcon(): NativeImage { + const iconPath = join( + __dirname, + '..', + '..', + 'images', + 'app-icon-with-error.png' + ); + return nativeImage.createFromPath(iconPath); +}