Improve error messaging for startup database error

This commit is contained in:
ayumi-signal 2025-03-24 10:19:02 -07:00 committed by GitHub
parent 3b04e05da1
commit c94849d3a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 17 deletions

View file

@ -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": "Cant 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": {

View file

@ -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');

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -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);
}