Improve error handling during group sends
This commit is contained in:
parent
f0a3735ca2
commit
991580a1ed
58 changed files with 299 additions and 324 deletions
|
@ -13,27 +13,28 @@ let quitText = 'Quit';
|
||||||
let copyErrorAndQuitText = 'Copy error and quit';
|
let copyErrorAndQuitText = 'Copy error and quit';
|
||||||
|
|
||||||
function handleError(prefix: string, error: Error): void {
|
function handleError(prefix: string, error: Error): void {
|
||||||
|
const formattedError = Errors.toLogFormat(error);
|
||||||
if (console._error) {
|
if (console._error) {
|
||||||
console._error(`${prefix}:`, Errors.toLogFormat(error));
|
console._error(`${prefix}:`, formattedError);
|
||||||
}
|
}
|
||||||
console.error(`${prefix}:`, Errors.toLogFormat(error));
|
console.error(`${prefix}:`, formattedError);
|
||||||
|
|
||||||
if (app.isReady()) {
|
if (app.isReady()) {
|
||||||
// title field is not shown on macOS, so we don't use it
|
// title field is not shown on macOS, so we don't use it
|
||||||
const buttonIndex = dialog.showMessageBoxSync({
|
const buttonIndex = dialog.showMessageBoxSync({
|
||||||
buttons: [quitText, copyErrorAndQuitText],
|
buttons: [quitText, copyErrorAndQuitText],
|
||||||
defaultId: 0,
|
defaultId: 0,
|
||||||
detail: redactAll(error.stack || ''),
|
detail: redactAll(formattedError),
|
||||||
message: prefix,
|
message: prefix,
|
||||||
noLink: true,
|
noLink: true,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (buttonIndex === 1) {
|
if (buttonIndex === 1) {
|
||||||
clipboard.writeText(`${prefix}\n\n${redactAll(error.stack || '')}`);
|
clipboard.writeText(`${prefix}\n\n${redactAll(formattedError)}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dialog.showErrorBox(prefix, error.stack || '');
|
dialog.showErrorBox(prefix, formattedError);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.exit(1);
|
app.exit(1);
|
||||||
|
|
32
app/main.ts
32
app/main.ts
|
@ -46,6 +46,7 @@ import { strictAssert } from '../ts/util/assert';
|
||||||
import { consoleLogger } from '../ts/util/consoleLogger';
|
import { consoleLogger } from '../ts/util/consoleLogger';
|
||||||
import type { ThemeSettingType } from '../ts/types/StorageUIKeys';
|
import type { ThemeSettingType } from '../ts/types/StorageUIKeys';
|
||||||
import { ThemeType } from '../ts/types/Util';
|
import { ThemeType } from '../ts/types/Util';
|
||||||
|
import * as Errors from '../ts/types/errors';
|
||||||
|
|
||||||
import './startup_config';
|
import './startup_config';
|
||||||
|
|
||||||
|
@ -471,7 +472,7 @@ async function handleUrl(event: Electron.Event, rawTarget: string) {
|
||||||
try {
|
try {
|
||||||
await shell.openExternal(target);
|
await shell.openExternal(target);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
getLogger().error(`Failed to open url: ${error.stack}`);
|
getLogger().error(`Failed to open url: ${Errors.toLogFormat(error)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,7 +939,7 @@ ipc.handle('database-ready', async () => {
|
||||||
if (error) {
|
if (error) {
|
||||||
getLogger().error(
|
getLogger().error(
|
||||||
'database-ready requested, but got sql error',
|
'database-ready requested, but got sql error',
|
||||||
error && error.stack
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1029,7 +1030,7 @@ async function readyForUpdates() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
getLogger().error(
|
getLogger().error(
|
||||||
'Error starting update checks:',
|
'Error starting update checks:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1039,10 +1040,7 @@ async function forceUpdate() {
|
||||||
getLogger().info('starting force update');
|
getLogger().info('starting force update');
|
||||||
await updater.force();
|
await updater.force();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
getLogger().error(
|
getLogger().error('Error during force update:', Errors.toLogFormat(error));
|
||||||
'Error during force update:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1477,7 +1475,7 @@ const runSQLCorruptionHandler = async () => {
|
||||||
`Restarting the application immediately. Error: ${error.message}`
|
`Restarting the application immediately. Error: ${error.message}`
|
||||||
);
|
);
|
||||||
|
|
||||||
await onDatabaseError(error.stack || error.message);
|
await onDatabaseError(Errors.toLogFormat(error));
|
||||||
};
|
};
|
||||||
|
|
||||||
async function initializeSQL(
|
async function initializeSQL(
|
||||||
|
@ -1796,7 +1794,7 @@ app.on('ready', async () => {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(
|
logger.error(
|
||||||
'main/ready: Error deleting temp dir:',
|
'main/ready: Error deleting temp dir:',
|
||||||
err && err.stack ? err.stack : err
|
Errors.toLogFormat(err)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1823,7 +1821,7 @@ app.on('ready', async () => {
|
||||||
if (sqlError) {
|
if (sqlError) {
|
||||||
getLogger().error('sql.initialize was unsuccessful; returning early');
|
getLogger().error('sql.initialize was unsuccessful; returning early');
|
||||||
|
|
||||||
await onDatabaseError(sqlError.stack || sqlError.message);
|
await onDatabaseError(Errors.toLogFormat(sqlError));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1840,7 +1838,7 @@ app.on('ready', async () => {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
getLogger().error(
|
getLogger().error(
|
||||||
'(ready event handler) error deleting IndexedDB:',
|
'(ready event handler) error deleting IndexedDB:',
|
||||||
err && err.stack ? err.stack : err
|
Errors.toLogFormat(err)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1949,10 +1947,7 @@ async function requestShutdown() {
|
||||||
try {
|
try {
|
||||||
await request;
|
await request;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
getLogger().error(
|
getLogger().error('requestShutdown error:', Errors.toLogFormat(error));
|
||||||
'requestShutdown error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2157,7 +2152,7 @@ ipc.handle(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
getLogger().error(
|
getLogger().error(
|
||||||
'show-permissions-popup error:',
|
'show-permissions-popup error:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2200,7 +2195,10 @@ ipc.on('get-built-in-images', async () => {
|
||||||
if (mainWindow && mainWindow.webContents) {
|
if (mainWindow && mainWindow.webContents) {
|
||||||
mainWindow.webContents.send('get-success-built-in-images', error.message);
|
mainWindow.webContents.send('get-success-built-in-images', error.message);
|
||||||
} else {
|
} else {
|
||||||
getLogger().error('Error handling get-built-in-images:', error.stack);
|
getLogger().error(
|
||||||
|
'Error handling get-built-in-images:',
|
||||||
|
Errors.toLogFormat(error)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { app } from 'electron';
|
||||||
|
|
||||||
import { start } from './base_config';
|
import { start } from './base_config';
|
||||||
import config from './config';
|
import config from './config';
|
||||||
|
import * as Errors from '../ts/types/errors';
|
||||||
|
|
||||||
let userData: string | undefined;
|
let userData: string | undefined;
|
||||||
// Use separate data directory for benchmarks & development
|
// Use separate data directory for benchmarks & development
|
||||||
|
@ -23,7 +24,7 @@ if (userData !== undefined) {
|
||||||
try {
|
try {
|
||||||
mkdirSync(userData, { recursive: true });
|
mkdirSync(userData, { recursive: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to create userData', error?.stack || String(error));
|
console.error('Failed to create userData', Errors.toLogFormat(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
app.setPath('userData', userData);
|
app.setPath('userData', userData);
|
||||||
|
|
|
@ -13,7 +13,9 @@ import type { Props as DropZoneProps } from '../elements/DropZone';
|
||||||
import { DropZone } from '../elements/DropZone';
|
import { DropZone } from '../elements/DropZone';
|
||||||
import { processStickerImage } from '../util/preload';
|
import { processStickerImage } from '../util/preload';
|
||||||
import { useI18n } from '../util/i18n';
|
import { useI18n } from '../util/i18n';
|
||||||
|
import { ProcessStickerImageError } from '../errors';
|
||||||
import { MINUTE } from '../../ts/util/durations';
|
import { MINUTE } from '../../ts/util/durations';
|
||||||
|
import * as Errors from '../../ts/types/errors';
|
||||||
|
|
||||||
const queue = new PQueue({ concurrency: 3, timeout: MINUTE * 30 });
|
const queue = new PQueue({ concurrency: 3, timeout: MINUTE * 30 });
|
||||||
|
|
||||||
|
@ -64,13 +66,16 @@ const InnerGrid = SortableContainer(
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.SignalContext.log.error(
|
window.SignalContext.log.error(
|
||||||
'Error processing image:',
|
'Error processing image:',
|
||||||
e?.stack ? e.stack : String(e)
|
Errors.toLogFormat(e)
|
||||||
);
|
);
|
||||||
actions.removeSticker(path);
|
actions.removeSticker(path);
|
||||||
|
|
||||||
|
const key =
|
||||||
|
e instanceof ProcessStickerImageError
|
||||||
|
? e.errorMessageI18nKey
|
||||||
|
: 'StickerCreator--Toasts--errorProcessing';
|
||||||
actions.addToast({
|
actions.addToast({
|
||||||
key:
|
key,
|
||||||
(e || {}).errorMessageI18nKey ||
|
|
||||||
'StickerCreator--Toasts--errorProcessing',
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
8
sticker-creator/errors.ts
Normal file
8
sticker-creator/errors.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright 2022 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
export class ProcessStickerImageError extends Error {
|
||||||
|
constructor(message: string, public readonly errorMessageI18nKey: string) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import { initialize as initializeWebAPI } from '../../ts/textsecure/WebAPI';
|
||||||
|
|
||||||
import { SignalContext } from '../../ts/windows/context';
|
import { SignalContext } from '../../ts/windows/context';
|
||||||
import { getAnimatedPngDataIfExists } from '../../ts/util/getAnimatedPngDataIfExists';
|
import { getAnimatedPngDataIfExists } from '../../ts/util/getAnimatedPngDataIfExists';
|
||||||
|
import { ProcessStickerImageError } from '../errors';
|
||||||
|
|
||||||
const STICKER_SIZE = 512;
|
const STICKER_SIZE = 512;
|
||||||
const MIN_STICKER_DIMENSION = 10;
|
const MIN_STICKER_DIMENSION = 10;
|
||||||
|
@ -42,12 +43,6 @@ const WebAPI = initializeWebAPI({
|
||||||
version: config.version,
|
version: config.version,
|
||||||
});
|
});
|
||||||
|
|
||||||
function processStickerError(message: string, i18nKey: string): Error {
|
|
||||||
const result = new Error(message);
|
|
||||||
result.errorMessageI18nKey = i18nKey;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.processStickerImage = async (path: string | undefined) => {
|
window.processStickerImage = async (path: string | undefined) => {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
throw new Error(`Path ${path} is not valid!`);
|
throw new Error(`Path ${path} is not valid!`);
|
||||||
|
@ -59,7 +54,7 @@ window.processStickerImage = async (path: string | undefined) => {
|
||||||
|
|
||||||
const { width, height } = meta;
|
const { width, height } = meta;
|
||||||
if (!width || !height) {
|
if (!width || !height) {
|
||||||
throw processStickerError(
|
throw new ProcessStickerImageError(
|
||||||
'Sticker height or width were falsy',
|
'Sticker height or width were falsy',
|
||||||
'StickerCreator--Toasts--errorProcessing'
|
'StickerCreator--Toasts--errorProcessing'
|
||||||
);
|
);
|
||||||
|
@ -75,31 +70,31 @@ window.processStickerImage = async (path: string | undefined) => {
|
||||||
const animatedPngDataIfExists = getAnimatedPngDataIfExists(imgBuffer);
|
const animatedPngDataIfExists = getAnimatedPngDataIfExists(imgBuffer);
|
||||||
if (animatedPngDataIfExists) {
|
if (animatedPngDataIfExists) {
|
||||||
if (imgBuffer.byteLength > MAX_STICKER_BYTE_LENGTH) {
|
if (imgBuffer.byteLength > MAX_STICKER_BYTE_LENGTH) {
|
||||||
throw processStickerError(
|
throw new ProcessStickerImageError(
|
||||||
'Sticker file was too large',
|
'Sticker file was too large',
|
||||||
'StickerCreator--Toasts--tooLarge'
|
'StickerCreator--Toasts--tooLarge'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (width !== height) {
|
if (width !== height) {
|
||||||
throw processStickerError(
|
throw new ProcessStickerImageError(
|
||||||
'Sticker must be square',
|
'Sticker must be square',
|
||||||
'StickerCreator--Toasts--APNG--notSquare'
|
'StickerCreator--Toasts--APNG--notSquare'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (width > MAX_STICKER_DIMENSION) {
|
if (width > MAX_STICKER_DIMENSION) {
|
||||||
throw processStickerError(
|
throw new ProcessStickerImageError(
|
||||||
'Sticker dimensions are too large',
|
'Sticker dimensions are too large',
|
||||||
'StickerCreator--Toasts--APNG--dimensionsTooLarge'
|
'StickerCreator--Toasts--APNG--dimensionsTooLarge'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (width < MIN_STICKER_DIMENSION) {
|
if (width < MIN_STICKER_DIMENSION) {
|
||||||
throw processStickerError(
|
throw new ProcessStickerImageError(
|
||||||
'Sticker dimensions are too small',
|
'Sticker dimensions are too small',
|
||||||
'StickerCreator--Toasts--APNG--dimensionsTooSmall'
|
'StickerCreator--Toasts--APNG--dimensionsTooSmall'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (animatedPngDataIfExists.numPlays !== Infinity) {
|
if (animatedPngDataIfExists.numPlays !== Infinity) {
|
||||||
throw processStickerError(
|
throw new ProcessStickerImageError(
|
||||||
'Animated stickers must loop forever',
|
'Animated stickers must loop forever',
|
||||||
'StickerCreator--Toasts--mustLoopForever'
|
'StickerCreator--Toasts--mustLoopForever'
|
||||||
);
|
);
|
||||||
|
@ -118,7 +113,7 @@ window.processStickerImage = async (path: string | undefined) => {
|
||||||
.webp()
|
.webp()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
if (processedBuffer.byteLength > MAX_STICKER_BYTE_LENGTH) {
|
if (processedBuffer.byteLength > MAX_STICKER_BYTE_LENGTH) {
|
||||||
throw processStickerError(
|
throw new ProcessStickerImageError(
|
||||||
'Sticker file was too large',
|
'Sticker file was too large',
|
||||||
'StickerCreator--Toasts--tooLarge'
|
'StickerCreator--Toasts--tooLarge'
|
||||||
);
|
);
|
||||||
|
|
|
@ -299,7 +299,7 @@ export class ConversationController {
|
||||||
log.error(
|
log.error(
|
||||||
'Contact is not valid. Not saving, but adding to collection:',
|
'Contact is not valid. Not saving, but adding to collection:',
|
||||||
conversation.idForLogging(),
|
conversation.idForLogging(),
|
||||||
validationError.stack
|
Errors.toLogFormat(validationError)
|
||||||
);
|
);
|
||||||
|
|
||||||
return conversation;
|
return conversation;
|
||||||
|
@ -316,7 +316,7 @@ export class ConversationController {
|
||||||
identifier,
|
identifier,
|
||||||
type,
|
type,
|
||||||
'Error:',
|
'Error:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -1247,7 +1247,7 @@ export class ConversationController {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'ConversationController.load/map: Failed to prepare a conversation',
|
'ConversationController.load/map: Failed to prepare a conversation',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1256,7 +1256,7 @@ export class ConversationController {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'ConversationController: initial fetch failed',
|
'ConversationController: initial fetch failed',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -392,7 +392,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'removePreKey error triggering removePreKey:',
|
'removePreKey error triggering removePreKey:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,7 +604,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
await this.commitZoneChanges('saveSenderKey');
|
await this.commitZoneChanges('saveSenderKey');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = Errors.toLogFormat(error);
|
||||||
log.error(
|
log.error(
|
||||||
`saveSenderKey: failed to save senderKey ${senderId}/${distributionId}: ${errorString}`
|
`saveSenderKey: failed to save senderKey ${senderId}/${distributionId}: ${errorString}`
|
||||||
);
|
);
|
||||||
|
@ -653,7 +653,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
log.info('Successfully fetched sender key(cache miss):', id);
|
log.info('Successfully fetched sender key(cache miss):', id);
|
||||||
return item;
|
return item;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = Errors.toLogFormat(error);
|
||||||
log.error(
|
log.error(
|
||||||
`getSenderKey: failed to load sender key ${senderId}/${distributionId}: ${errorString}`
|
`getSenderKey: failed to load sender key ${senderId}/${distributionId}: ${errorString}`
|
||||||
);
|
);
|
||||||
|
@ -679,7 +679,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
|
|
||||||
this.senderKeys.delete(id);
|
this.senderKeys.delete(id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = Errors.toLogFormat(error);
|
||||||
log.error(
|
log.error(
|
||||||
`removeSenderKey: failed to remove senderKey ${senderId}/${distributionId}: ${errorString}`
|
`removeSenderKey: failed to remove senderKey ${senderId}/${distributionId}: ${errorString}`
|
||||||
);
|
);
|
||||||
|
@ -860,7 +860,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
`pending sender keys size ${this.pendingSenderKeys.size}, ` +
|
`pending sender keys size ${this.pendingSenderKeys.size}, ` +
|
||||||
`pending sessions size ${this.pendingSessions.size}, ` +
|
`pending sessions size ${this.pendingSessions.size}, ` +
|
||||||
`pending unprocessed size ${this.pendingUnprocessed.size}`,
|
`pending unprocessed size ${this.pendingUnprocessed.size}`,
|
||||||
error && error.stack
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
this.pendingSenderKeys.clear();
|
this.pendingSenderKeys.clear();
|
||||||
this.pendingSessions.clear();
|
this.pendingSessions.clear();
|
||||||
|
@ -961,7 +961,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
// and save it to the database.
|
// and save it to the database.
|
||||||
return await this._maybeMigrateSession(entry.fromDB, { zone });
|
return await this._maybeMigrateSession(entry.fromDB, { zone });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = Errors.toLogFormat(error);
|
||||||
log.error(`loadSession: failed to load session ${id}: ${errorString}`);
|
log.error(`loadSession: failed to load session ${id}: ${errorString}`);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -1095,7 +1095,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
await this.commitZoneChanges('storeSession');
|
await this.commitZoneChanges('storeSession');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = Errors.toLogFormat(error);
|
||||||
log.error(`storeSession: Save failed for ${id}: ${errorString}`);
|
log.error(`storeSession: Save failed for ${id}: ${errorString}`);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -1189,7 +1189,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'getOpenDevices: Failed to get devices',
|
'getOpenDevices: Failed to get devices',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -1692,7 +1692,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'saveIdentity: error triggering keychange:',
|
'saveIdentity: error triggering keychange:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -609,7 +609,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.info(
|
log.info(
|
||||||
'User chose not to delete old data. Shutting down.',
|
'User chose not to delete old data. Shutting down.',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
window.shutdown();
|
window.shutdown();
|
||||||
return;
|
return;
|
||||||
|
@ -627,7 +627,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Failed to remove IndexedDB file or remove SQL data:',
|
'Failed to remove IndexedDB file or remove SQL data:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,7 +859,7 @@ export async function startApp(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await window.Signal.Data.startInRendererProcess();
|
await window.Signal.Data.startInRendererProcess();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error('SQL failed to initialize', err && err.stack ? err.stack : err);
|
log.error('SQL failed to initialize', Errors.toLogFormat(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
setAppLoadingScreenMessage(window.i18n('loading'), window.i18n);
|
setAppLoadingScreenMessage(window.i18n('loading'), window.i18n);
|
||||||
|
@ -950,7 +950,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
'background/setInterval: Failed to parse integer from desktop.retryRespondMaxAge feature flag',
|
'background/setInterval: Failed to parse integer from desktop.retryRespondMaxAge feature flag',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -961,7 +961,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'background/onready/setInterval: Error deleting sent protos: ',
|
'background/onready/setInterval: Error deleting sent protos: ',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -991,7 +991,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'background/onready/setInterval: Error getting expired retry placeholders: ',
|
'background/onready/setInterval: Error getting expired retry placeholders: ',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, FIVE_MINUTES);
|
}, FIVE_MINUTES);
|
||||||
|
@ -1038,7 +1038,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'background.js: ConversationController failed to load:',
|
'background.js: ConversationController failed to load:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
initializeRedux({ mainWindowStats, menuOptions });
|
initializeRedux({ mainWindowStats, menuOptions });
|
||||||
|
@ -2140,7 +2140,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'connect: Error refreshing remote config:',
|
'connect: Error refreshing remote config:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2226,7 +2226,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error(
|
log.error(
|
||||||
'Problem with account manager updates after starting new version: ',
|
'Problem with account manager updates after starting new version: ',
|
||||||
e && e.stack ? e.stack : e
|
Errors.toLogFormat(e)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2239,7 +2239,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Error: Unable to register for unauthenticated delivery support.',
|
'Error: Unable to register for unauthenticated delivery support.',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2270,7 +2270,7 @@ export async function startApp(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Error: Unable to register our capabilities.',
|
'Error: Unable to register our capabilities.',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2859,7 +2859,10 @@ export async function startApp(): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error('respondWithProfileKeyBatcher error', error && error.stack);
|
log.error(
|
||||||
|
'respondWithProfileKeyBatcher error',
|
||||||
|
Errors.toLogFormat(error)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.queueJob('sendProfileKeyUpdate', () =>
|
sender.queueJob('sendProfileKeyUpdate', () =>
|
||||||
|
@ -3521,7 +3524,7 @@ export async function startApp(): Promise<void> {
|
||||||
log.error(
|
log.error(
|
||||||
'unlinkAndDisconnect: Something went wrong clearing ' +
|
'unlinkAndDisconnect: Something went wrong clearing ' +
|
||||||
'local configuration',
|
'local configuration',
|
||||||
eraseError && eraseError.stack ? eraseError.stack : eraseError
|
Errors.toLogFormat(eraseError)
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
window.Signal.Util.Registration.markEverDone();
|
window.Signal.Util.Registration.markEverDone();
|
||||||
|
|
|
@ -15,6 +15,7 @@ import type { ExecuteMenuRoleType } from './TitleBarContainer';
|
||||||
import { ToastLoadingFullLogs } from './ToastLoadingFullLogs';
|
import { ToastLoadingFullLogs } from './ToastLoadingFullLogs';
|
||||||
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';
|
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';
|
||||||
import { createSupportUrl } from '../util/createSupportUrl';
|
import { createSupportUrl } from '../util/createSupportUrl';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import { useEscapeHandling } from '../hooks/useEscapeHandling';
|
import { useEscapeHandling } from '../hooks/useEscapeHandling';
|
||||||
import { useTheme } from '../hooks/useTheme';
|
import { useTheme } from '../hooks/useTheme';
|
||||||
|
|
||||||
|
@ -107,10 +108,7 @@ export function DebugLogWindow({
|
||||||
const publishedLogURL = await uploadLogs(text);
|
const publishedLogURL = await uploadLogs(text);
|
||||||
setPublicLogURL(publishedLogURL);
|
setPublicLogURL(publishedLogURL);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('DebugLogWindow error:', Errors.toLogFormat(error));
|
||||||
'DebugLogWindow error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
setLoadState(LoadState.Loaded);
|
setLoadState(LoadState.Loaded);
|
||||||
setToastType(ToastType.Error);
|
setToastType(ToastType.Error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
getImageDimensions,
|
getImageDimensions,
|
||||||
defaultBlurHash,
|
defaultBlurHash,
|
||||||
} from '../../types/Attachment';
|
} from '../../types/Attachment';
|
||||||
|
import * as Errors from '../../types/errors';
|
||||||
import * as log from '../../logging/log';
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
const MAX_GIF_REPEAT = 4;
|
const MAX_GIF_REPEAT = 4;
|
||||||
|
@ -90,7 +91,7 @@ export function GIF(props: Props): JSX.Element {
|
||||||
video.play().catch(error => {
|
video.play().catch(error => {
|
||||||
log.info(
|
log.info(
|
||||||
"Failed to match GIF playback to window's state",
|
"Failed to match GIF playback to window's state",
|
||||||
(error && error.stack) || error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
53
ts/groups.ts
53
ts/groups.ts
|
@ -453,7 +453,10 @@ async function uploadAvatar(
|
||||||
key,
|
key,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(`uploadAvatar/${logId} Failed to upload avatar`, error.stack);
|
log.warn(
|
||||||
|
`uploadAvatar/${logId} Failed to upload avatar`,
|
||||||
|
Errors.toLogFormat(error)
|
||||||
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2391,7 +2394,7 @@ export async function initiateMigrationToGroupV2(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`initiateMigrationToGroupV2/${logId}: Error creating group:`,
|
`initiateMigrationToGroupV2/${logId}: Error creating group:`,
|
||||||
error.stack
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -2473,7 +2476,7 @@ export async function waitThenRespondToGroupV2Migration(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`waitThenRespondToGroupV2Migration/${conversation.idForLogging()}: respondToGroupV2Migration failure:`,
|
`waitThenRespondToGroupV2Migration/${conversation.idForLogging()}: respondToGroupV2Migration failure:`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2946,7 +2949,7 @@ export async function waitThenMaybeUpdateGroup(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: maybeUpdateGroup failure:`,
|
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: maybeUpdateGroup failure:`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2984,7 +2987,7 @@ export async function maybeUpdateGroup(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`maybeUpdateGroup/${logId}: Failed to update group:`,
|
`maybeUpdateGroup/${logId}: Failed to update group:`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -3910,7 +3913,7 @@ async function integrateGroupChanges({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`integrateGroupChanges/${logId}: Failed to apply change log, continuing to apply remaining change logs.`,
|
`integrateGroupChanges/${logId}: Failed to apply change log, continuing to apply remaining change logs.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5287,7 +5290,7 @@ export async function applyNewAvatar(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`applyNewAvatar/${logId} Failed to handle avatar, clearing it`,
|
`applyNewAvatar/${logId} Failed to handle avatar, clearing it`,
|
||||||
error.stack
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
if (result.avatar && result.avatar.path) {
|
if (result.avatar && result.avatar.path) {
|
||||||
await window.Signal.Migrations.deleteAttachmentData(result.avatar.path);
|
await window.Signal.Migrations.deleteAttachmentData(result.avatar.path);
|
||||||
|
@ -5622,7 +5625,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt sourceUuid.`,
|
`decryptGroupChange/${logId}: Unable to decrypt sourceUuid.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5677,7 +5680,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt deleteMembers.deletedUserId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt deleteMembers.deletedUserId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -5711,7 +5714,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt modifyMemberRole.userId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt modifyMemberRole.userId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -5844,7 +5847,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt deletePendingMembers.deletedUserId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt deletePendingMembers.deletedUserId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -6022,7 +6025,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt modifyTitle.title`,
|
`decryptGroupChange/${logId}: Unable to decrypt modifyTitle.title`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -6049,7 +6052,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt modifyDisappearingMessagesTimer.timer`,
|
`decryptGroupChange/${logId}: Unable to decrypt modifyDisappearingMessagesTimer.timer`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -6152,7 +6155,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt deletePendingApproval.deletedUserId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt deletePendingApproval.deletedUserId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -6190,7 +6193,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt promoteAdminApproval.userId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt promoteAdminApproval.userId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -6232,7 +6235,7 @@ function decryptGroupChange(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt modifyDescription.descriptionBytes`,
|
`decryptGroupChange/${logId}: Unable to decrypt modifyDescription.descriptionBytes`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -6365,7 +6368,7 @@ function decryptGroupState(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupState/${logId}: Unable to decrypt title. Clearing it.`,
|
`decryptGroupState/${logId}: Unable to decrypt title. Clearing it.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6388,7 +6391,7 @@ function decryptGroupState(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupState/${logId}: Unable to decrypt disappearing message timer. Clearing it.`,
|
`decryptGroupState/${logId}: Unable to decrypt disappearing message timer. Clearing it.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6472,7 +6475,7 @@ function decryptGroupState(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptGroupState/${logId}: Unable to decrypt descriptionBytes. Clearing it.`,
|
`decryptGroupState/${logId}: Unable to decrypt descriptionBytes. Clearing it.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6537,7 +6540,7 @@ function decryptMember(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptMember/${logId}: Unable to decrypt member userid. Dropping member.`,
|
`decryptMember/${logId}: Unable to decrypt member userid. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -6608,7 +6611,7 @@ function decryptMemberPendingProfileKey(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member addedByUserId. Dropping member.`,
|
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member addedByUserId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -6648,7 +6651,7 @@ function decryptMemberPendingProfileKey(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member userId. Dropping member.`,
|
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member userId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -6673,7 +6676,7 @@ function decryptMemberPendingProfileKey(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member profileKey. Dropping profileKey.`,
|
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member profileKey. Dropping profileKey.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6735,7 +6738,7 @@ function decryptMemberPendingAdminApproval(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt pending member userId. Dropping member.`,
|
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt pending member userId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -6760,7 +6763,7 @@ function decryptMemberPendingAdminApproval(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt profileKey. Dropping profileKey.`,
|
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt profileKey. Dropping profileKey.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { read as readLastLines } from 'read-last-lines';
|
||||||
import rimraf from 'rimraf';
|
import rimraf from 'rimraf';
|
||||||
|
|
||||||
import type { LoggerType } from '../types/Logging';
|
import type { LoggerType } from '../types/Logging';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import * as durations from '../util/durations';
|
import * as durations from '../util/durations';
|
||||||
import { createRotatingPinoDest } from '../util/rotatingPinoDest';
|
import { createRotatingPinoDest } from '../util/rotatingPinoDest';
|
||||||
|
|
||||||
|
@ -67,7 +68,9 @@ export async function initialize(
|
||||||
try {
|
try {
|
||||||
await cleanupLogs(logPath);
|
await cleanupLogs(logPath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = `Failed to clean logs; deleting all. Error: ${error.stack}`;
|
const errorString =
|
||||||
|
'Failed to clean logs; deleting all. ' +
|
||||||
|
`Error: ${Errors.toLogFormat(error)}`;
|
||||||
console.error(errorString);
|
console.error(errorString);
|
||||||
await deleteAllLogs(logPath);
|
await deleteAllLogs(logPath);
|
||||||
mkdirp.sync(logPath);
|
mkdirp.sync(logPath);
|
||||||
|
@ -136,7 +139,7 @@ export async function initialize(
|
||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Problem loading log data: ${error.stack}`);
|
logger.error(`Problem loading log data: ${Errors.toLogFormat(error)}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +154,7 @@ export async function initialize(
|
||||||
try {
|
try {
|
||||||
await deleteAllLogs(logPath);
|
await deleteAllLogs(logPath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Problem deleting all logs: ${error.stack}`);
|
logger.error(`Problem deleting all logs: ${Errors.toLogFormat(error)}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -196,7 +199,7 @@ async function cleanupLogs(logPath: string) {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(
|
console.error(
|
||||||
'Error cleaning logs; deleting and starting over from scratch.',
|
'Error cleaning logs; deleting and starting over from scratch.',
|
||||||
error.stack
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
|
|
||||||
// delete and re-create the log directory
|
// delete and re-create the log directory
|
||||||
|
@ -215,7 +218,7 @@ export function isLineAfterDate(line: string, date: Readonly<Date>): boolean {
|
||||||
const data = JSON.parse(line);
|
const data = JSON.parse(line);
|
||||||
return new Date(data.time).getTime() > date.getTime();
|
return new Date(data.time).getTime() > date.getTime();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('error parsing log line', e.stack, line);
|
console.log('error parsing log line', Errors.toLogFormat(e), line);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {
|
||||||
} from './shared';
|
} from './shared';
|
||||||
import * as log from './log';
|
import * as log from './log';
|
||||||
import { Environment, getEnvironment } from '../environment';
|
import { Environment, getEnvironment } from '../environment';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import { createRotatingPinoDest } from '../util/rotatingPinoDest';
|
import { createRotatingPinoDest } from '../util/rotatingPinoDest';
|
||||||
|
|
||||||
// Backwards-compatible logging, simple strings and no level (defaulted to INFO)
|
// Backwards-compatible logging, simple strings and no level (defaulted to INFO)
|
||||||
|
@ -114,14 +115,13 @@ window.SignalContext.log = {
|
||||||
};
|
};
|
||||||
|
|
||||||
window.onerror = (_message, _script, _line, _col, error) => {
|
window.onerror = (_message, _script, _line, _col, error) => {
|
||||||
const errorInfo = error && error.stack ? error.stack : JSON.stringify(error);
|
const errorInfo = Errors.toLogFormat(error);
|
||||||
log.error(`Top-level unhandled error: ${errorInfo}`);
|
log.error(`Top-level unhandled error: ${errorInfo}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('unhandledrejection', rejectionEvent => {
|
window.addEventListener('unhandledrejection', rejectionEvent => {
|
||||||
const error = rejectionEvent.reason;
|
const error = rejectionEvent.reason;
|
||||||
const errorString =
|
const errorString = Errors.toLogFormat(error);
|
||||||
error && error.stack ? error.stack : JSON.stringify(error);
|
|
||||||
log.error(`Top-level unhandled promise rejection: ${errorString}`);
|
log.error(`Top-level unhandled promise rejection: ${errorString}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { Collection, Model } from 'backbone';
|
||||||
import type { MessageModel } from '../models/messages';
|
import type { MessageModel } from '../models/messages';
|
||||||
import { getContactId } from '../messages/helpers';
|
import { getContactId } from '../messages/helpers';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import { deleteForEveryone } from '../util/deleteForEveryone';
|
import { deleteForEveryone } from '../util/deleteForEveryone';
|
||||||
|
|
||||||
export type DeleteAttributesType = {
|
export type DeleteAttributesType = {
|
||||||
|
@ -97,10 +98,7 @@ export class Deletes extends Collection<DeleteModel> {
|
||||||
this.remove(del);
|
this.remove(del);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('Deletes.onDelete error:', Errors.toLogFormat(error));
|
||||||
'Deletes.onDelete error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { getOwn } from '../util/getOwn';
|
||||||
import { missingCaseError } from '../util/missingCaseError';
|
import { missingCaseError } from '../util/missingCaseError';
|
||||||
import { createWaitBatcher } from '../util/waitBatcher';
|
import { createWaitBatcher } from '../util/waitBatcher';
|
||||||
import type { UUIDStringType } from '../types/UUID';
|
import type { UUIDStringType } from '../types/UUID';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import {
|
import {
|
||||||
SendActionType,
|
SendActionType,
|
||||||
SendStatus,
|
SendStatus,
|
||||||
|
@ -331,10 +332,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
|
||||||
|
|
||||||
this.remove(receipt);
|
this.remove(receipt);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('MessageReceipts.onReceipt error:', Errors.toLogFormat(error));
|
||||||
'MessageReceipts.onReceipt error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import { Collection, Model } from 'backbone';
|
import { Collection, Model } from 'backbone';
|
||||||
import type { ConversationModel } from '../models/conversations';
|
import type { ConversationModel } from '../models/conversations';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
export type MessageRequestAttributesType = {
|
export type MessageRequestAttributesType = {
|
||||||
threadE164?: string;
|
threadE164?: string;
|
||||||
|
@ -122,10 +123,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
|
||||||
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('MessageRequests.onResponse error:', Errors.toLogFormat(error));
|
||||||
'MessageRequests.onResponse error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import type {
|
||||||
MessageAttributesType,
|
MessageAttributesType,
|
||||||
ReactionAttributesType,
|
ReactionAttributesType,
|
||||||
} from '../model-types.d';
|
} from '../model-types.d';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
import { getContactId, getContact } from '../messages/helpers';
|
import { getContactId, getContact } from '../messages/helpers';
|
||||||
import { isDirectConversation, isMe } from '../util/whatTypeOfConversation';
|
import { isDirectConversation, isMe } from '../util/whatTypeOfConversation';
|
||||||
|
@ -213,10 +214,7 @@ export class Reactions extends Collection<ReactionModel> {
|
||||||
this.remove(reaction);
|
this.remove(reaction);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('Reactions.onReaction error:', Errors.toLogFormat(error));
|
||||||
'Reactions.onReaction error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { isIncoming } from '../state/selectors/message';
|
||||||
import { isMessageUnread } from '../util/isMessageUnread';
|
import { isMessageUnread } from '../util/isMessageUnread';
|
||||||
import { notificationService } from '../services/notifications';
|
import { notificationService } from '../services/notifications';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
export type ReadSyncAttributesType = {
|
export type ReadSyncAttributesType = {
|
||||||
senderId: string;
|
senderId: string;
|
||||||
|
@ -142,10 +143,7 @@ export class ReadSyncs extends Collection {
|
||||||
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('ReadSyncs.onSync error:', Errors.toLogFormat(error));
|
||||||
'ReadSyncs.onSync error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import { Collection, Model } from 'backbone';
|
import { Collection, Model } from 'backbone';
|
||||||
import type { MessageModel } from '../models/messages';
|
import type { MessageModel } from '../models/messages';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
export type ViewOnceOpenSyncAttributesType = {
|
export type ViewOnceOpenSyncAttributesType = {
|
||||||
source?: string;
|
source?: string;
|
||||||
|
@ -94,10 +95,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
|
||||||
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('ViewOnceOpenSyncs.onSync error:', Errors.toLogFormat(error));
|
||||||
'ViewOnceOpenSyncs.onSync error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import type { MessageModel } from '../models/messages';
|
||||||
import { ReadStatus } from '../messages/MessageReadStatus';
|
import { ReadStatus } from '../messages/MessageReadStatus';
|
||||||
import { markViewed } from '../services/MessageUpdater';
|
import { markViewed } from '../services/MessageUpdater';
|
||||||
import { isDownloaded } from '../types/Attachment';
|
import { isDownloaded } from '../types/Attachment';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import { isIncoming } from '../state/selectors/message';
|
import { isIncoming } from '../state/selectors/message';
|
||||||
import { notificationService } from '../services/notifications';
|
import { notificationService } from '../services/notifications';
|
||||||
import { queueAttachmentDownloads } from '../util/queueAttachmentDownloads';
|
import { queueAttachmentDownloads } from '../util/queueAttachmentDownloads';
|
||||||
|
@ -111,10 +112,7 @@ export class ViewSyncs extends Collection {
|
||||||
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('ViewSyncs.onSync error:', Errors.toLogFormat(error));
|
||||||
'ViewSyncs.onSync error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1242,7 +1242,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`Error erasing data for message ${this.idForLogging()}:`,
|
`Error erasing data for message ${this.idForLogging()}:`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1358,11 +1358,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
errors.forEach(e => {
|
errors.forEach(e => {
|
||||||
log.error(
|
log.error('Message.saveErrors:', Errors.toLogFormat(e));
|
||||||
'Message.saveErrors:',
|
|
||||||
e && e.reason ? e.reason : null,
|
|
||||||
e && e.stack ? e.stack : e
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
errors = errors.map(e => {
|
errors = errors.map(e => {
|
||||||
// Note: in our environment, instanceof can be scary, so we have a backup check
|
// Note: in our environment, instanceof can be scary, so we have a backup check
|
||||||
|
@ -2415,7 +2411,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
sentAt: message.get('sent_at'),
|
sentAt: message.get('sent_at'),
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorText = error && error.stack ? error.stack : error;
|
const errorText = Errors.toLogFormat(error);
|
||||||
log.error(
|
log.error(
|
||||||
`${idLog}: Failed to process group update as part of message ${message.idForLogging()}: ${errorText}`
|
`${idLog}: Failed to process group update as part of message ${message.idForLogging()}: ${errorText}`
|
||||||
);
|
);
|
||||||
|
@ -3050,7 +3046,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
log.info(`${idLog}: Batching save`);
|
log.info(`${idLog}: Batching save`);
|
||||||
this.saveAndNotify(conversation, confirm);
|
this.saveAndNotify(conversation, confirm);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorForLog = error && error.stack ? error.stack : error;
|
const errorForLog = Errors.toLogFormat(error);
|
||||||
log.error(`${idLog}: error:`, errorForLog);
|
log.error(`${idLog}: error:`, errorForLog);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ export async function routineProfileRefresh({
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(
|
log.error(
|
||||||
`${logId}: refreshed profile for ${conversation.idForLogging()}`,
|
`${logId}: refreshed profile for ${conversation.idForLogging()}`,
|
||||||
err?.stack || err
|
Errors.toLogFormat(err)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import type {
|
||||||
MaybeGrabLinkPreviewOptionsType,
|
MaybeGrabLinkPreviewOptionsType,
|
||||||
AddLinkPreviewOptionsType,
|
AddLinkPreviewOptionsType,
|
||||||
} from '../types/LinkPreview';
|
} from '../types/LinkPreview';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import type { StickerPackType as StickerPackDBType } from '../sql/Interface';
|
import type { StickerPackType as StickerPackDBType } from '../sql/Interface';
|
||||||
import type { MIMEType } from '../types/MIME';
|
import type { MIMEType } from '../types/MIME';
|
||||||
import * as Bytes from '../Bytes';
|
import * as Bytes from '../Bytes';
|
||||||
|
@ -216,7 +217,7 @@ export async function addLinkPreview(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Problem loading link preview, disabling.',
|
'Problem loading link preview, disabling.',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
disableLinkPreviews = true;
|
disableLinkPreviews = true;
|
||||||
removeLinkPreview();
|
removeLinkPreview();
|
||||||
|
@ -455,10 +456,7 @@ async function getStickerPackPreview(
|
||||||
url,
|
url,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('getStickerPackPreview error:', Errors.toLogFormat(error));
|
||||||
'getStickerPackPreview error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
} finally {
|
} finally {
|
||||||
if (id) {
|
if (id) {
|
||||||
|
@ -530,7 +528,7 @@ async function getGroupPreview(
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = Errors.toLogFormat(error);
|
||||||
log.error(
|
log.error(
|
||||||
`getGroupPreview/${logId}: Failed to fetch avatar ${errorString}`
|
`getGroupPreview/${logId}: Failed to fetch avatar ${errorString}`
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import { requestMicrophonePermissions } from '../util/requestMicrophonePermissions';
|
import { requestMicrophonePermissions } from '../util/requestMicrophonePermissions';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
import type { WebAudioRecorderClass } from '../window.d';
|
import type { WebAudioRecorderClass } from '../window.d';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
export class RecorderClass {
|
export class RecorderClass {
|
||||||
private context?: AudioContext;
|
private context?: AudioContext;
|
||||||
|
@ -84,10 +85,7 @@ export class RecorderClass {
|
||||||
this.source.connect(this.input);
|
this.source.connect(this.input);
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(
|
log.error('Recorder.onGetUserMediaError:', Errors.toLogFormat(err));
|
||||||
'Recorder.onGetUserMediaError:',
|
|
||||||
err && err.stack ? err.stack : err
|
|
||||||
);
|
|
||||||
this.clear();
|
this.clear();
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +133,7 @@ export class RecorderClass {
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
|
|
||||||
log.error('Recorder/onError:', error && error.stack ? error.stack : error);
|
log.error('Recorder/onError:', Errors.toLogFormat(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
getBlob(): Blob {
|
getBlob(): Blob {
|
||||||
|
|
|
@ -67,6 +67,7 @@ import {
|
||||||
} from '../calling/findBestMatchingDevice';
|
} from '../calling/findBestMatchingDevice';
|
||||||
import type { LocalizerType } from '../types/Util';
|
import type { LocalizerType } from '../types/Util';
|
||||||
import { UUID, UUIDKind } from '../types/UUID';
|
import { UUID, UUIDKind } from '../types/UUID';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import type { ConversationModel } from '../models/conversations';
|
import type { ConversationModel } from '../models/conversations';
|
||||||
import * as Bytes from '../Bytes';
|
import * as Bytes from '../Bytes';
|
||||||
import { uuidToBytes, bytesToUuid } from '../Crypto';
|
import { uuidToBytes, bytesToUuid } from '../Crypto';
|
||||||
|
@ -1061,10 +1062,7 @@ export class CallingClass {
|
||||||
sendType: 'callingMessage',
|
sendType: 'callingMessage',
|
||||||
timestamp,
|
timestamp,
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
log.error(
|
log.error('Failed to send group call update:', Errors.toLogFormat(err));
|
||||||
'Failed to send group call update:',
|
|
||||||
err && err.stack ? err.stack : err
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1877,7 +1875,7 @@ export class CallingClass {
|
||||||
|
|
||||||
return await this.getCallSettings(conversation);
|
return await this.getCallSettings(conversation);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(`Ignoring incoming call: ${err.stack}`);
|
log.error(`Ignoring incoming call: ${Errors.toLogFormat(err)}`);
|
||||||
this.addCallHistoryForFailedIncomingCall(
|
this.addCallHistoryForFailedIncomingCall(
|
||||||
conversation,
|
conversation,
|
||||||
call.isVideoCall,
|
call.isVideoCall,
|
||||||
|
|
|
@ -7,6 +7,7 @@ import type { MessageModel } from '../models/messages';
|
||||||
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
||||||
import { sleep } from '../util/sleep';
|
import { sleep } from '../util/sleep';
|
||||||
import { SECOND } from '../util/durations';
|
import { SECOND } from '../util/durations';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
class ExpiringMessagesDeletionService {
|
class ExpiringMessagesDeletionService {
|
||||||
public update: typeof this.checkExpiringMessages;
|
public update: typeof this.checkExpiringMessages;
|
||||||
|
@ -65,7 +66,7 @@ class ExpiringMessagesDeletionService {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.SignalContext.log.error(
|
window.SignalContext.log.error(
|
||||||
'destroyExpiredMessages: Error deleting expired messages',
|
'destroyExpiredMessages: Error deleting expired messages',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
window.SignalContext.log.info(
|
window.SignalContext.log.info(
|
||||||
'destroyExpiredMessages: Waiting 30 seconds before trying again'
|
'destroyExpiredMessages: Waiting 30 seconds before trying again'
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { missingCaseError } from '../util/missingCaseError';
|
||||||
import { waitForOnline } from '../util/waitForOnline';
|
import { waitForOnline } from '../util/waitForOnline';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
import type { StorageInterface } from '../types/Storage.d';
|
import type { StorageInterface } from '../types/Storage.d';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import type { WebAPIType } from '../textsecure/WebAPI';
|
import type { WebAPIType } from '../textsecure/WebAPI';
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
|
|
||||||
|
@ -171,7 +172,7 @@ export class SenderCertificateService {
|
||||||
`Sender certificate service could not fetch a ${modeToLogString(
|
`Sender certificate service could not fetch a ${modeToLogString(
|
||||||
mode
|
mode
|
||||||
)} certificate. Returning undefined`,
|
)} certificate. Returning undefined`,
|
||||||
err && err.stack ? err.stack : err
|
Errors.toLogFormat(err)
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
||||||
import { DAY } from '../util/durations';
|
import { DAY } from '../util/durations';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
async function eraseTapToViewMessages() {
|
async function eraseTapToViewMessages() {
|
||||||
try {
|
try {
|
||||||
|
@ -30,7 +31,7 @@ async function eraseTapToViewMessages() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.SignalContext.log.error(
|
window.SignalContext.log.error(
|
||||||
'eraseTapToViewMessages: Error erasing messages',
|
'eraseTapToViewMessages: Error erasing messages',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
import { deleteAllLogs } from '../util/deleteAllLogs';
|
import { deleteAllLogs } from '../util/deleteAllLogs';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
export async function deleteAllData(): Promise<void> {
|
export async function deleteAllData(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
@ -28,7 +29,7 @@ export async function deleteAllData(): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Something went wrong deleting all data:',
|
'Something went wrong deleting all data:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
window.restart();
|
window.restart();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import { parentPort } from 'worker_threads';
|
import { parentPort } from 'worker_threads';
|
||||||
|
|
||||||
import type { LoggerType } from '../types/Logging';
|
import type { LoggerType } from '../types/Logging';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import type {
|
import type {
|
||||||
WrappedWorkerRequest,
|
WrappedWorkerRequest,
|
||||||
WrappedWorkerResponse,
|
WrappedWorkerResponse,
|
||||||
|
@ -22,7 +23,7 @@ function respond(seq: number, error: Error | undefined, response?: any) {
|
||||||
const wrappedResponse: WrappedWorkerResponse = {
|
const wrappedResponse: WrappedWorkerResponse = {
|
||||||
type: 'response',
|
type: 'response',
|
||||||
seq,
|
seq,
|
||||||
error: error?.stack,
|
error: error === undefined ? undefined : Errors.toLogFormat(error),
|
||||||
response,
|
response,
|
||||||
};
|
};
|
||||||
port.postMessage(wrappedResponse);
|
port.postMessage(wrappedResponse);
|
||||||
|
|
|
@ -55,6 +55,7 @@ import { CallMode } from '../../types/Calling';
|
||||||
import type { MediaItemType } from '../../types/MediaItem';
|
import type { MediaItemType } from '../../types/MediaItem';
|
||||||
import type { UUIDStringType } from '../../types/UUID';
|
import type { UUIDStringType } from '../../types/UUID';
|
||||||
import { MY_STORY_ID, StorySendMode } from '../../types/Stories';
|
import { MY_STORY_ID, StorySendMode } from '../../types/Stories';
|
||||||
|
import * as Errors from '../../types/errors';
|
||||||
import {
|
import {
|
||||||
getGroupSizeRecommendedLimit,
|
getGroupSizeRecommendedLimit,
|
||||||
getGroupSizeHardLimit,
|
getGroupSizeHardLimit,
|
||||||
|
@ -1206,7 +1207,7 @@ function myProfileChanged(
|
||||||
payload: null,
|
payload: null,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error('myProfileChanged', err && err.stack ? err.stack : err);
|
log.error('myProfileChanged', Errors.toLogFormat(err));
|
||||||
dispatch({ type: TOGGLE_PROFILE_EDITOR_ERROR });
|
dispatch({ type: TOGGLE_PROFILE_EDITOR_ERROR });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1606,7 +1607,7 @@ function createGroup(
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error('Failed to create group', err && err.stack ? err.stack : err);
|
log.error('Failed to create group', Errors.toLogFormat(err));
|
||||||
dispatch({ type: 'CREATE_GROUP_REJECTED' });
|
dispatch({ type: 'CREATE_GROUP_REJECTED' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
toggleVerification,
|
toggleVerification,
|
||||||
} from '../../shims/contactVerification';
|
} from '../../shims/contactVerification';
|
||||||
import * as log from '../../logging/log';
|
import * as log from '../../logging/log';
|
||||||
|
import * as Errors from '../../types/errors';
|
||||||
|
|
||||||
export type SafetyNumberContactType = {
|
export type SafetyNumberContactType = {
|
||||||
safetyNumber: string;
|
safetyNumber: string;
|
||||||
|
@ -108,10 +109,7 @@ async function alterVerification(contact: ConversationType): Promise<void> {
|
||||||
if (result.name === 'OutgoingIdentityKeyError') {
|
if (result.name === 'OutgoingIdentityKeyError') {
|
||||||
throw result;
|
throw result;
|
||||||
} else {
|
} else {
|
||||||
log.error(
|
log.error('failed to toggle verified:', Errors.toLogFormat(result));
|
||||||
'failed to toggle verified:',
|
|
||||||
result && result.stack ? result.stack : result
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const keyError = result.errors.find(
|
const keyError = result.errors.find(
|
||||||
|
@ -121,10 +119,7 @@ async function alterVerification(contact: ConversationType): Promise<void> {
|
||||||
throw keyError;
|
throw keyError;
|
||||||
} else {
|
} else {
|
||||||
result.errors.forEach((error: Error) => {
|
result.errors.forEach((error: Error) => {
|
||||||
log.error(
|
log.error('failed to toggle verified:', Errors.toLogFormat(error));
|
||||||
'failed to toggle verified:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import type { StateType } from '../reducer';
|
||||||
import * as log from '../../logging/log';
|
import * as log from '../../logging/log';
|
||||||
import { ForwardMessageModal } from '../../components/ForwardMessageModal';
|
import { ForwardMessageModal } from '../../components/ForwardMessageModal';
|
||||||
import { LinkPreviewSourceType } from '../../types/LinkPreview';
|
import { LinkPreviewSourceType } from '../../types/LinkPreview';
|
||||||
|
import * as Errors from '../../types/errors';
|
||||||
import type { GetConversationByIdType } from '../selectors/conversations';
|
import type { GetConversationByIdType } from '../selectors/conversations';
|
||||||
import {
|
import {
|
||||||
getAllComposableConversations,
|
getAllComposableConversations,
|
||||||
|
@ -107,7 +108,7 @@ export function SmartForwardMessageModal(): JSX.Element | null {
|
||||||
closeModal();
|
closeModal();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.warn('doForwardMessage', err && err.stack ? err.stack : err);
|
log.warn('doForwardMessage', Errors.toLogFormat(err));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
getPreferredBadge={getPreferredBadge}
|
getPreferredBadge={getPreferredBadge}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
|
import { LibSignalErrorBase } from '@signalapp/libsignal-client';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
_analyzeSenderKeyDevices,
|
_analyzeSenderKeyDevices,
|
||||||
|
@ -172,7 +173,11 @@ describe('sendToGroup', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns true for any error with 'untrusted' identity", async () => {
|
it("returns true for any error with 'untrusted' identity", async () => {
|
||||||
const error = new Error('This was an untrusted identity.');
|
const error = new LibSignalErrorBase(
|
||||||
|
'untrusted identity',
|
||||||
|
'UntrustedIdentity',
|
||||||
|
'ignored'
|
||||||
|
);
|
||||||
assert.isTrue(_shouldFailSend(error, 'logId'));
|
assert.isTrue(_shouldFailSend(error, 'logId'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -575,7 +575,7 @@ export default class AccountManager extends EventTarget {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Something went wrong deleting data from previous number',
|
'Something went wrong deleting data from previous number',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import protobuf from '../protobuf/wrap';
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
import { normalizeUuid } from '../util/normalizeUuid';
|
import { normalizeUuid } from '../util/normalizeUuid';
|
||||||
import { DurationInSeconds } from '../util/durations';
|
import { DurationInSeconds } from '../util/durations';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
import Avatar = Proto.ContactDetails.IAvatar;
|
import Avatar = Proto.ContactDetails.IAvatar;
|
||||||
|
@ -90,10 +91,7 @@ abstract class ParserBase<
|
||||||
expireTimer,
|
expireTimer,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error('ProtoParser.next error:', Errors.toLogFormat(error));
|
||||||
'ProtoParser.next error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,9 @@ export class ReplayableError extends Error {
|
||||||
name?: string;
|
name?: string;
|
||||||
message: string;
|
message: string;
|
||||||
functionCode?: number;
|
functionCode?: number;
|
||||||
|
cause?: unknown;
|
||||||
}) {
|
}) {
|
||||||
super(options.message);
|
super(options.message, { cause: options.cause });
|
||||||
|
|
||||||
this.name = options.name || 'ReplayableError';
|
this.name = options.name || 'ReplayableError';
|
||||||
this.message = options.message;
|
this.message = options.message;
|
||||||
|
@ -71,7 +72,7 @@ export class ReplayableError extends Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OutgoingIdentityKeyError extends ReplayableError {
|
export class OutgoingIdentityKeyError extends ReplayableError {
|
||||||
identifier: string;
|
public readonly identifier: string;
|
||||||
|
|
||||||
// Note: Data to resend message is no longer captured
|
// Note: Data to resend message is no longer captured
|
||||||
constructor(incomingIdentifier: string) {
|
constructor(incomingIdentifier: string) {
|
||||||
|
@ -162,6 +163,7 @@ export class SendMessageChallengeError extends ReplayableError {
|
||||||
super({
|
super({
|
||||||
name: 'SendMessageChallengeError',
|
name: 'SendMessageChallengeError',
|
||||||
message: httpError.message,
|
message: httpError.message,
|
||||||
|
cause: httpError,
|
||||||
});
|
});
|
||||||
|
|
||||||
[this.identifier] = identifier.split('.');
|
[this.identifier] = identifier.split('.');
|
||||||
|
@ -237,9 +239,7 @@ export class SendMessageProtoError extends Error implements CallbackResultType {
|
||||||
return 'No errors';
|
return 'No errors';
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors
|
return errors.map(error => error.toString()).join(', ');
|
||||||
.map(error => (error.stackForLog ? error.stackForLog : error.toString()))
|
|
||||||
.join(', ');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ import type {
|
||||||
PlaintextContent,
|
PlaintextContent,
|
||||||
} from '@signalapp/libsignal-client';
|
} from '@signalapp/libsignal-client';
|
||||||
import {
|
import {
|
||||||
|
ErrorCode,
|
||||||
|
LibSignalErrorBase,
|
||||||
CiphertextMessageType,
|
CiphertextMessageType,
|
||||||
ProtocolAddress,
|
ProtocolAddress,
|
||||||
sealedSenderEncrypt,
|
sealedSenderEncrypt,
|
||||||
|
@ -34,6 +36,7 @@ import {
|
||||||
import type { CallbackResultType, CustomError } from './Types.d';
|
import type { CallbackResultType, CustomError } from './Types.d';
|
||||||
import { isValidNumber } from '../types/PhoneNumber';
|
import { isValidNumber } from '../types/PhoneNumber';
|
||||||
import { Address } from '../types/Address';
|
import { Address } from '../types/Address';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import { QualifiedAddress } from '../types/QualifiedAddress';
|
import { QualifiedAddress } from '../types/QualifiedAddress';
|
||||||
import { UUID, isValidUuid } from '../types/UUID';
|
import { UUID, isValidUuid } from '../types/UUID';
|
||||||
import { Sessions, IdentityKeys } from '../LibSignalStores';
|
import { Sessions, IdentityKeys } from '../LibSignalStores';
|
||||||
|
@ -244,8 +247,7 @@ export default class OutgoingMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error.reason = reason;
|
error.cause = reason;
|
||||||
error.stackForLog = providedError ? providedError.stack : undefined;
|
|
||||||
|
|
||||||
this.errors[this.errors.length] = error;
|
this.errors[this.errors.length] = error;
|
||||||
this.numberCompleted();
|
this.numberCompleted();
|
||||||
|
@ -284,7 +286,6 @@ export default class OutgoingMessage {
|
||||||
: { accessKey: undefined };
|
: { accessKey: undefined };
|
||||||
const { accessKey } = info;
|
const { accessKey } = info;
|
||||||
|
|
||||||
try {
|
|
||||||
const { accessKeyFailed } = await getKeysForIdentifier(
|
const { accessKeyFailed } = await getKeysForIdentifier(
|
||||||
identifier,
|
identifier,
|
||||||
this.server,
|
this.server,
|
||||||
|
@ -294,12 +295,6 @@ export default class OutgoingMessage {
|
||||||
if (accessKeyFailed && !this.failoverIdentifiers.includes(identifier)) {
|
if (accessKeyFailed && !this.failoverIdentifiers.includes(identifier)) {
|
||||||
this.failoverIdentifiers.push(identifier);
|
this.failoverIdentifiers.push(identifier);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
if (error?.message?.includes('untrusted identity for address')) {
|
|
||||||
error.timestamp = this.timestamp;
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async transmitMessage(
|
async transmitMessage(
|
||||||
|
@ -626,8 +621,13 @@ export default class OutgoingMessage {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error?.message?.includes('untrusted identity for address')) {
|
|
||||||
error.timestamp = this.timestamp;
|
let newError = error;
|
||||||
|
if (
|
||||||
|
error instanceof LibSignalErrorBase &&
|
||||||
|
error.code === ErrorCode.UntrustedIdentity
|
||||||
|
) {
|
||||||
|
newError = new OutgoingIdentityKeyError(identifier);
|
||||||
log.error(
|
log.error(
|
||||||
'Got "key changed" error from encrypt - no identityKey for application layer',
|
'Got "key changed" error from encrypt - no identityKey for application layer',
|
||||||
identifier,
|
identifier,
|
||||||
|
@ -643,7 +643,8 @@ export default class OutgoingMessage {
|
||||||
},
|
},
|
||||||
innerError => {
|
innerError => {
|
||||||
log.error(
|
log.error(
|
||||||
`doSendMessage: Error closing sessions: ${innerError.stack}`
|
'doSendMessage: Error closing sessions: ' +
|
||||||
|
`${Errors.toLogFormat(innerError)}`
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -653,7 +654,7 @@ export default class OutgoingMessage {
|
||||||
this.registerError(
|
this.registerError(
|
||||||
identifier,
|
identifier,
|
||||||
'Failed to create or send message',
|
'Failed to create or send message',
|
||||||
error
|
newError
|
||||||
);
|
);
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -712,7 +713,7 @@ export default class OutgoingMessage {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`sendToIdentifier: Failed to fetch UUID for identifier ${identifier}`,
|
`sendToIdentifier: Failed to fetch UUID for identifier ${identifier}`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -731,7 +732,10 @@ export default class OutgoingMessage {
|
||||||
}
|
}
|
||||||
await this.reloadDevicesAndSend(identifier, true)();
|
await this.reloadDevicesAndSend(identifier, true)();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error?.message?.includes('untrusted identity for address')) {
|
if (
|
||||||
|
error instanceof LibSignalErrorBase &&
|
||||||
|
error.code === ErrorCode.UntrustedIdentity
|
||||||
|
) {
|
||||||
const newError = new OutgoingIdentityKeyError(identifier);
|
const newError = new OutgoingIdentityKeyError(identifier);
|
||||||
this.registerError(identifier, 'Untrusted identity', newError);
|
this.registerError(identifier, 'Untrusted identity', newError);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ErrorCode,
|
||||||
|
LibSignalErrorBase,
|
||||||
PreKeyBundle,
|
PreKeyBundle,
|
||||||
processPreKeyBundle,
|
processPreKeyBundle,
|
||||||
ProtocolAddress,
|
ProtocolAddress,
|
||||||
|
@ -9,9 +11,9 @@ import {
|
||||||
} from '@signalapp/libsignal-client';
|
} from '@signalapp/libsignal-client';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
OutgoingIdentityKeyError,
|
||||||
UnregisteredUserError,
|
UnregisteredUserError,
|
||||||
HTTPError,
|
HTTPError,
|
||||||
OutgoingIdentityKeyError,
|
|
||||||
} from './Errors';
|
} from './Errors';
|
||||||
import { Sessions, IdentityKeys } from '../LibSignalStores';
|
import { Sessions, IdentityKeys } from '../LibSignalStores';
|
||||||
import { Address } from '../types/Address';
|
import { Address } from '../types/Address';
|
||||||
|
@ -72,13 +74,6 @@ async function getServerKeys(
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (
|
|
||||||
error instanceof Error &&
|
|
||||||
error.message.includes('untrusted identity')
|
|
||||||
) {
|
|
||||||
throw new OutgoingIdentityKeyError(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
accessKey &&
|
accessKey &&
|
||||||
isRecord(error) &&
|
isRecord(error) &&
|
||||||
|
@ -155,22 +150,27 @@ async function handleServerKeys(
|
||||||
ourUuid,
|
ourUuid,
|
||||||
new Address(theirUuid, deviceId)
|
new Address(theirUuid, deviceId)
|
||||||
);
|
);
|
||||||
await window.textsecure.storage.protocol
|
|
||||||
.enqueueSessionJob(address, () =>
|
try {
|
||||||
|
await window.textsecure.storage.protocol.enqueueSessionJob(
|
||||||
|
address,
|
||||||
|
() =>
|
||||||
processPreKeyBundle(
|
processPreKeyBundle(
|
||||||
preKeyBundle,
|
preKeyBundle,
|
||||||
protocolAddress,
|
protocolAddress,
|
||||||
sessionStore,
|
sessionStore,
|
||||||
identityKeyStore
|
identityKeyStore
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
.catch(error => {
|
} catch (error) {
|
||||||
if (error?.message?.includes('untrusted identity for address')) {
|
if (
|
||||||
// eslint-disable-next-line no-param-reassign
|
error instanceof LibSignalErrorBase &&
|
||||||
error.identityKey = response.identityKey;
|
error.code === ErrorCode.UntrustedIdentity
|
||||||
|
) {
|
||||||
|
throw new OutgoingIdentityKeyError(identifier);
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
});
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -529,7 +529,7 @@ export async function downloadEphemeralPack(
|
||||||
}
|
}
|
||||||
log.error(
|
log.error(
|
||||||
`Ephemeral download error for sticker pack ${redactPackId(packId)}:`,
|
`Ephemeral download error for sticker pack ${redactPackId(packId)}:`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ export async function downloadStickerPack(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'doDownloadStickerPack threw an error:',
|
'doDownloadStickerPack threw an error:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -696,7 +696,7 @@ async function doDownloadStickerPack(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`Error downloading manifest for sticker pack ${redactPackId(packId)}:`,
|
`Error downloading manifest for sticker pack ${redactPackId(packId)}:`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
|
|
||||||
const pack = {
|
const pack = {
|
||||||
|
@ -779,7 +779,7 @@ async function doDownloadStickerPack(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`Error downloading stickers for sticker pack ${redactPackId(packId)}:`,
|
`Error downloading stickers for sticker pack ${redactPackId(packId)}:`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
|
|
||||||
const errorStatus = 'error';
|
const errorStatus = 'error';
|
||||||
|
|
|
@ -4,15 +4,20 @@
|
||||||
import { get, has } from 'lodash';
|
import { get, has } from 'lodash';
|
||||||
|
|
||||||
export function toLogFormat(error: unknown): string {
|
export function toLogFormat(error: unknown): string {
|
||||||
|
let result = '';
|
||||||
if (error instanceof Error && error.stack) {
|
if (error instanceof Error && error.stack) {
|
||||||
return error.stack;
|
result = error.stack;
|
||||||
|
} else if (has(error, 'message')) {
|
||||||
|
result = get(error, 'message');
|
||||||
|
} else {
|
||||||
|
result = String(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has(error, 'message')) {
|
if (has(error, 'cause')) {
|
||||||
return get(error, 'message');
|
result += `\nCaused by: ${String(get(error, 'cause'))}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return String(error);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProfileDecryptError extends Error {}
|
export class ProfileDecryptError extends Error {}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import { getEnvironment, Environment } from '../environment';
|
import { getEnvironment, Environment } from '../environment';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In production and beta, logs a warning and continues. For development it
|
* In production and beta, logs a warning and continues. For development it
|
||||||
|
@ -15,7 +16,7 @@ export function softAssert(condition: unknown, message: string): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const err = new Error(message);
|
const err = new Error(message);
|
||||||
log.warn('softAssert failure:', err && err.stack ? err.stack : err);
|
log.warn('softAssert failure:', Errors.toLogFormat(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ export function assertDev(
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
log.error('assert failure:', err && err.stack ? err.stack : err);
|
log.error('assert failure:', Errors.toLogFormat(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,11 @@ import { getValue } from '../RemoteConfig';
|
||||||
|
|
||||||
import { parseIntOrThrow } from './parseIntOrThrow';
|
import { parseIntOrThrow } from './parseIntOrThrow';
|
||||||
import { scaleImageToLevel } from './scaleImageToLevel';
|
import { scaleImageToLevel } from './scaleImageToLevel';
|
||||||
import { isRecord } from './isRecord';
|
|
||||||
import type { AttachmentType } from '../types/Attachment';
|
import type { AttachmentType } from '../types/Attachment';
|
||||||
import { canBeTranscoded } from '../types/Attachment';
|
import { canBeTranscoded } from '../types/Attachment';
|
||||||
import type { LoggerType } from '../types/Logging';
|
import type { LoggerType } from '../types/Logging';
|
||||||
import * as MIME from '../types/MIME';
|
import * as MIME from '../types/MIME';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
const MEBIBYTE = 1024 * 1024;
|
const MEBIBYTE = 1024 * 1024;
|
||||||
const DEFAULT_MAX = 100 * MEBIBYTE;
|
const DEFAULT_MAX = 100 * MEBIBYTE;
|
||||||
|
@ -87,8 +87,7 @@ export async function autoOrientJPEG(
|
||||||
|
|
||||||
return xcodedAttachment;
|
return xcodedAttachment;
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const errorString =
|
const errorString = Errors.toLogFormat(error);
|
||||||
isRecord(error) && 'stack' in error ? error.stack : error;
|
|
||||||
logger.error(
|
logger.error(
|
||||||
'autoOrientJPEG: Failed to rotate/scale attachment',
|
'autoOrientJPEG: Failed to rotate/scale attachment',
|
||||||
errorString
|
errorString
|
||||||
|
|
|
@ -14,6 +14,7 @@ import type {
|
||||||
DefaultConversationColorType,
|
DefaultConversationColorType,
|
||||||
} from '../types/Colors';
|
} from '../types/Colors';
|
||||||
import { DEFAULT_CONVERSATION_COLOR } from '../types/Colors';
|
import { DEFAULT_CONVERSATION_COLOR } from '../types/Colors';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import * as Stickers from '../types/Stickers';
|
import * as Stickers from '../types/Stickers';
|
||||||
import type { SystemTraySetting } from '../types/SystemTraySetting';
|
import type { SystemTraySetting } from '../types/SystemTraySetting';
|
||||||
import { parseSystemTraySetting } from '../types/SystemTraySetting';
|
import { parseSystemTraySetting } from '../types/SystemTraySetting';
|
||||||
|
@ -453,7 +454,7 @@ export function createIPCEvents(
|
||||||
window.isShowingModal = false;
|
window.isShowingModal = false;
|
||||||
log.error(
|
log.error(
|
||||||
'showStickerPack: Ran into an error!',
|
'showStickerPack: Ran into an error!',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
const errorView = new ReactWrapperView({
|
const errorView = new ReactWrapperView({
|
||||||
className: 'error-modal-wrapper',
|
className: 'error-modal-wrapper',
|
||||||
|
@ -483,7 +484,7 @@ export function createIPCEvents(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'showGroupViaLink: Ran into an error!',
|
'showGroupViaLink: Ran into an error!',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
const errorView = new ReactWrapperView({
|
const errorView = new ReactWrapperView({
|
||||||
className: 'error-modal-wrapper',
|
className: 'error-modal-wrapper',
|
||||||
|
|
|
@ -102,7 +102,7 @@ export async function onRetryRequest(event: RetryRequestEvent): Promise<void> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`onRetryRequest/${logId}: Failed to parse integer from desktop.retryRespondMaxAge feature flag`,
|
`onRetryRequest/${logId}: Failed to parse integer from desktop.retryRespondMaxAge feature flag`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ async function sendDistributionMessageOrNullMessage(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`sendDistributionMessageOrNullMessage/${logId}: Failed to send sender key distribution message`,
|
`sendDistributionMessageOrNullMessage/${logId}: Failed to send sender key distribution message`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -651,7 +651,7 @@ async function requestResend(decryptionError: DecryptionErrorEventData) {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`requestResend/${logId}: Failed to send retry request, failing over to automatic reset`,
|
`requestResend/${logId}: Failed to send retry request, failing over to automatic reset`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
startAutomaticSessionReset(decryptionError);
|
startAutomaticSessionReset(decryptionError);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import { Environment, getEnvironment } from '../environment';
|
import { Environment, getEnvironment } from '../environment';
|
||||||
import { isInPast } from './timestamp';
|
import { isInPast } from './timestamp';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
const ONE_DAY_MS = 86400 * 1000;
|
const ONE_DAY_MS = 86400 * 1000;
|
||||||
const NINETY_ONE_DAYS = 91 * ONE_DAY_MS;
|
const NINETY_ONE_DAYS = 91 * ONE_DAY_MS;
|
||||||
|
@ -18,7 +19,7 @@ export function hasExpired(): boolean {
|
||||||
log.info('Build expires: ', new Date(buildExpiration).toISOString());
|
log.info('Build expires: ', new Date(buildExpiration).toISOString());
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error('Error retrieving build expiration date', e.stack);
|
log.error('Error retrieving build expiration date', Errors.toLogFormat(e));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ const loadImageData = async (input: Input): Promise<ImageData> => {
|
||||||
canvasOrError => {
|
canvasOrError => {
|
||||||
if (canvasOrError instanceof Event && canvasOrError.type === 'error') {
|
if (canvasOrError instanceof Event && canvasOrError.type === 'error') {
|
||||||
const processError = new Error(
|
const processError = new Error(
|
||||||
'imageToBlurHash: Failed to process image'
|
'imageToBlurHash: Failed to process image',
|
||||||
|
{ cause: canvasOrError }
|
||||||
);
|
);
|
||||||
processError.originalError = canvasOrError;
|
|
||||||
reject(processError);
|
reject(processError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { ReactWrapperView } from '../views/ReactWrapperView';
|
||||||
import { ErrorModal } from '../components/ErrorModal';
|
import { ErrorModal } from '../components/ErrorModal';
|
||||||
import { ProgressModal } from '../components/ProgressModal';
|
import { ProgressModal } from '../components/ProgressModal';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import { clearTimeoutIfNecessary } from './clearTimeoutIfNecessary';
|
import { clearTimeoutIfNecessary } from './clearTimeoutIfNecessary';
|
||||||
|
|
||||||
export async function longRunningTaskWrapper<T>({
|
export async function longRunningTaskWrapper<T>({
|
||||||
|
@ -62,7 +63,7 @@ export async function longRunningTaskWrapper<T>({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`longRunningTaskWrapper/${idLog}: Error!`,
|
`longRunningTaskWrapper/${idLog}: Error!`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
|
|
||||||
clearTimeoutIfNecessary(progressTimeout);
|
clearTimeoutIfNecessary(progressTimeout);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import { ipcRenderer } from 'electron';
|
import { ipcRenderer } from 'electron';
|
||||||
|
|
||||||
import { strictAssert } from './assert';
|
import { strictAssert } from './assert';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import type { UnwrapPromise } from '../types/Util';
|
import type { UnwrapPromise } from '../types/Util';
|
||||||
import type {
|
import type {
|
||||||
IPCEventsValuesType,
|
IPCEventsValuesType,
|
||||||
|
@ -104,11 +105,7 @@ export function installSetting(
|
||||||
try {
|
try {
|
||||||
ipcRenderer.send('settings:response', seq, null, await getFn());
|
ipcRenderer.send('settings:response', seq, null, await getFn());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ipcRenderer.send(
|
ipcRenderer.send('settings:response', seq, Errors.toLogFormat(error));
|
||||||
'settings:response',
|
|
||||||
seq,
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -132,11 +129,7 @@ export function installSetting(
|
||||||
await setFn(value);
|
await setFn(value);
|
||||||
ipcRenderer.send('settings:response', seq, null);
|
ipcRenderer.send('settings:response', seq, null);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ipcRenderer.send(
|
ipcRenderer.send('settings:response', seq, Errors.toLogFormat(error));
|
||||||
'settings:response',
|
|
||||||
seq,
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -152,11 +145,7 @@ export function installCallback<Name extends keyof IPCEventsCallbacksType>(
|
||||||
try {
|
try {
|
||||||
ipcRenderer.send('settings:response', seq, null, await hook(...args));
|
ipcRenderer.send('settings:response', seq, null, await hook(...args));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ipcRenderer.send(
|
ipcRenderer.send('settings:response', seq, Errors.toLogFormat(error));
|
||||||
'settings:response',
|
|
||||||
seq,
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import type {
|
||||||
AttachmentDraftType,
|
AttachmentDraftType,
|
||||||
InMemoryAttachmentDraftType,
|
InMemoryAttachmentDraftType,
|
||||||
} from '../types/Attachment';
|
} from '../types/Attachment';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import { getMaximumAttachmentSize } from './attachments';
|
import { getMaximumAttachmentSize } from './attachments';
|
||||||
import { AttachmentToastType } from '../types/AttachmentToastType';
|
import { AttachmentToastType } from '../types/AttachmentToastType';
|
||||||
import { fileToBytes } from './fileToBytes';
|
import { fileToBytes } from './fileToBytes';
|
||||||
|
@ -105,7 +106,7 @@ export async function processAttachment(
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error(
|
log.error(
|
||||||
`Was unable to generate thumbnail for fileType ${fileType}`,
|
`Was unable to generate thumbnail for fileType ${fileType}`,
|
||||||
e && e.stack ? e.stack : e
|
Errors.toLogFormat(e)
|
||||||
);
|
);
|
||||||
const data = await fileToBytes(file);
|
const data = await fileToBytes(file);
|
||||||
attachment = {
|
attachment = {
|
||||||
|
@ -125,7 +126,7 @@ export async function processAttachment(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Error ensuring that image is properly sized:',
|
'Error ensuring that image is properly sized:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
|
|
|
@ -19,6 +19,7 @@ import type {
|
||||||
MessageAttributesType,
|
MessageAttributesType,
|
||||||
QuotedMessageType,
|
QuotedMessageType,
|
||||||
} from '../model-types.d';
|
} from '../model-types.d';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import type { StickerType } from '../types/Stickers';
|
import type { StickerType } from '../types/Stickers';
|
||||||
import type { LinkPreviewType } from '../types/message/LinkPreviews';
|
import type { LinkPreviewType } from '../types/message/LinkPreviews';
|
||||||
|
|
||||||
|
@ -222,7 +223,7 @@ export async function queueAttachmentDownloads(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`Problem copying sticker (${packId}, ${stickerId}) to attachments:`,
|
`Problem copying sticker (${packId}, ${stickerId}) to attachments:`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { IMAGE_JPEG } from '../types/MIME';
|
||||||
import { canvasToBlob } from './canvasToBlob';
|
import { canvasToBlob } from './canvasToBlob';
|
||||||
import { getValue } from '../RemoteConfig';
|
import { getValue } from '../RemoteConfig';
|
||||||
import { parseNumber } from './libphonenumberUtil';
|
import { parseNumber } from './libphonenumberUtil';
|
||||||
import { isRecord } from './isRecord';
|
|
||||||
|
|
||||||
enum MediaQualityLevels {
|
enum MediaQualityLevels {
|
||||||
One = 1,
|
One = 1,
|
||||||
|
@ -126,13 +125,10 @@ export async function scaleImageToLevel(
|
||||||
throw new Error('image not a canvas');
|
throw new Error('image not a canvas');
|
||||||
}
|
}
|
||||||
({ image } = data);
|
({ image } = data);
|
||||||
} catch (err) {
|
} catch (cause) {
|
||||||
const errorString = isRecord(err) && 'stack' in err ? err.stack : err;
|
const error = new Error('scaleImageToLevel: Failed to process image', {
|
||||||
const error = new Error(
|
cause,
|
||||||
'scaleImageToLevel: Failed to process image',
|
});
|
||||||
errorString
|
|
||||||
);
|
|
||||||
error.originalError = err;
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { differenceWith, omit, partition } from 'lodash';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ErrorCode,
|
ErrorCode,
|
||||||
|
LibSignalErrorBase,
|
||||||
groupEncrypt,
|
groupEncrypt,
|
||||||
ProtocolAddress,
|
ProtocolAddress,
|
||||||
sealedSenderMultiRecipientEncrypt,
|
sealedSenderMultiRecipientEncrypt,
|
||||||
|
@ -21,6 +22,7 @@ import {
|
||||||
import { Address } from '../types/Address';
|
import { Address } from '../types/Address';
|
||||||
import { QualifiedAddress } from '../types/QualifiedAddress';
|
import { QualifiedAddress } from '../types/QualifiedAddress';
|
||||||
import { UUID } from '../types/UUID';
|
import { UUID } from '../types/UUID';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import { getValue, isEnabled } from '../RemoteConfig';
|
import { getValue, isEnabled } from '../RemoteConfig';
|
||||||
import type { UUIDStringType } from '../types/UUID';
|
import type { UUIDStringType } from '../types/UUID';
|
||||||
import { isRecord } from './isRecord';
|
import { isRecord } from './isRecord';
|
||||||
|
@ -216,7 +218,7 @@ export async function sendContentMessageToGroup({
|
||||||
|
|
||||||
log.error(
|
log.error(
|
||||||
`sendToGroup/${logId}: Sender Key send failed, logging, proceeding to normal send`,
|
`sendToGroup/${logId}: Sender Key send failed, logging, proceeding to normal send`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,7 +583,10 @@ export async function sendToGroupViaSenderKey(options: {
|
||||||
recursionCount: recursionCount + 1,
|
recursionCount: recursionCount + 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error.code === ErrorCode.InvalidRegistrationId && error.addr) {
|
if (
|
||||||
|
error instanceof LibSignalErrorBase &&
|
||||||
|
error.code === ErrorCode.InvalidRegistrationId
|
||||||
|
) {
|
||||||
const address = error.addr as ProtocolAddress;
|
const address = error.addr as ProtocolAddress;
|
||||||
const name = address.name();
|
const name = address.name();
|
||||||
|
|
||||||
|
@ -742,7 +747,7 @@ function getSenderKeyExpireDuration(): number {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`getSenderKeyExpireDuration: Failed to parse integer. Using default of ${MAX_SENDER_KEY_EXPIRE_DURATION}.`,
|
`getSenderKeyExpireDuration: Failed to parse integer. Using default of ${MAX_SENDER_KEY_EXPIRE_DURATION}.`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return MAX_SENDER_KEY_EXPIRE_DURATION;
|
return MAX_SENDER_KEY_EXPIRE_DURATION;
|
||||||
}
|
}
|
||||||
|
@ -753,7 +758,10 @@ export function _shouldFailSend(error: unknown, logId: string): boolean {
|
||||||
log.error(`_shouldFailSend/${logId}: ${message}`);
|
log.error(`_shouldFailSend/${logId}: ${message}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (error instanceof Error && error.message.includes('untrusted identity')) {
|
if (
|
||||||
|
error instanceof LibSignalErrorBase &&
|
||||||
|
error.code === ErrorCode.UntrustedIdentity
|
||||||
|
) {
|
||||||
logError("'untrusted identity' error, failing.");
|
logError("'untrusted identity' error, failing.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1271,7 +1279,7 @@ async function fetchKeysForIdentifiers(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'fetchKeysForIdentifiers: Failed to fetch keys:',
|
'fetchKeysForIdentifiers: Failed to fetch keys:',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { render } from 'mustache';
|
||||||
import type { AttachmentType } from '../types/Attachment';
|
import type { AttachmentType } from '../types/Attachment';
|
||||||
import { isGIF } from '../types/Attachment';
|
import { isGIF } from '../types/Attachment';
|
||||||
import * as Stickers from '../types/Stickers';
|
import * as Stickers from '../types/Stickers';
|
||||||
|
import * as Errors from '../types/errors';
|
||||||
import type { DraftBodyRangesType } from '../types/Util';
|
import type { DraftBodyRangesType } from '../types/Util';
|
||||||
import type { MIMEType } from '../types/MIME';
|
import type { MIMEType } from '../types/MIME';
|
||||||
import type { ConversationModel } from '../models/conversations';
|
import type { ConversationModel } from '../models/conversations';
|
||||||
|
@ -1693,7 +1694,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Error sending delete-for-everyone',
|
'Error sending delete-for-everyone',
|
||||||
error && error.stack,
|
Errors.toLogFormat(error),
|
||||||
messageId
|
messageId
|
||||||
);
|
);
|
||||||
showToast(ToastDeleteForEveryoneFailed);
|
showToast(ToastDeleteForEveryoneFailed);
|
||||||
|
@ -2375,7 +2376,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
const { packId, stickerId } = options;
|
const { packId, stickerId } = options;
|
||||||
this.model.sendStickerMessage(packId, stickerId);
|
this.model.sendStickerMessage(packId, stickerId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error('clickSend error:', error && error.stack ? error.stack : error);
|
log.error('clickSend error:', Errors.toLogFormat(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2531,10 +2532,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.enableMessageField();
|
this.enableMessageField();
|
||||||
log.error(
|
log.error('sendMessage error:', Errors.toLogFormat(error));
|
||||||
'sendMessage error:',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2596,7 +2594,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
'Error pulling attached files before send',
|
'Error pulling attached files before send',
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
this.enableMessageField();
|
this.enableMessageField();
|
||||||
|
|
25
ts/window.d.ts
vendored
25
ts/window.d.ts
vendored
|
@ -3,13 +3,10 @@
|
||||||
|
|
||||||
// Captures the globals put in place by preload.js, background.js and others
|
// Captures the globals put in place by preload.js, background.js and others
|
||||||
|
|
||||||
/* eslint-disable max-classes-per-file */
|
|
||||||
|
|
||||||
import type { Store } from 'redux';
|
import type { Store } from 'redux';
|
||||||
import type * as Backbone from 'backbone';
|
import type * as Backbone from 'backbone';
|
||||||
import type * as Underscore from 'underscore';
|
import type * as Underscore from 'underscore';
|
||||||
import type PQueue from 'p-queue/dist';
|
import type PQueue from 'p-queue/dist';
|
||||||
import type { Ref } from 'react';
|
|
||||||
import type { assert } from 'chai';
|
import type { assert } from 'chai';
|
||||||
import type * as Mustache from 'mustache';
|
import type * as Mustache from 'mustache';
|
||||||
|
|
||||||
|
@ -358,15 +355,6 @@ declare global {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Error {
|
|
||||||
originalError?: Event;
|
|
||||||
reason?: unknown;
|
|
||||||
stackForLog?: string;
|
|
||||||
|
|
||||||
// Used in sticker creator to attach messages to errors
|
|
||||||
errorMessageI18nKey?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Element {
|
interface Element {
|
||||||
// WebKit-specific
|
// WebKit-specific
|
||||||
scrollIntoViewIfNeeded: (bringToCenter?: boolean) => void;
|
scrollIntoViewIfNeeded: (bringToCenter?: boolean) => void;
|
||||||
|
@ -387,19 +375,6 @@ declare global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GumVideoCapturer {
|
|
||||||
constructor(
|
|
||||||
maxWidth: number,
|
|
||||||
maxHeight: number,
|
|
||||||
maxFramerate: number,
|
|
||||||
localPreview: Ref<HTMLVideoElement>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CanvasVideoRenderer {
|
|
||||||
constructor(canvas: Ref<HTMLCanvasElement>);
|
|
||||||
}
|
|
||||||
|
|
||||||
export type WhisperType = {
|
export type WhisperType = {
|
||||||
Conversation: typeof ConversationModel;
|
Conversation: typeof ConversationModel;
|
||||||
ConversationCollection: typeof ConversationModelCollectionType;
|
ConversationCollection: typeof ConversationModelCollectionType;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { ThemeType } from '../../types/Util';
|
||||||
import { getEnvironment, Environment } from '../../environment';
|
import { getEnvironment, Environment } from '../../environment';
|
||||||
import { SignalContext } from '../context';
|
import { SignalContext } from '../context';
|
||||||
import * as log from '../../logging/log';
|
import * as log from '../../logging/log';
|
||||||
|
import * as Errors from '../../types/errors';
|
||||||
|
|
||||||
import { strictAssert } from '../../util/assert';
|
import { strictAssert } from '../../util/assert';
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ window.isBeforeVersion = (toCheck, baseVersion) => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +102,7 @@ window.isAfterVersion = (toCheck, baseVersion) => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(
|
log.error(
|
||||||
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
||||||
error && error.stack ? error.stack : error
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +306,7 @@ ipc.on('delete-all-data', async () => {
|
||||||
try {
|
try {
|
||||||
await deleteAllData();
|
await deleteAllData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error('delete-all-data: error', error && error.stack);
|
log.error('delete-all-data: error', Errors.toLogFormat(error));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -362,10 +363,7 @@ ipc.on('get-ready-for-shutdown', async () => {
|
||||||
await shutdown();
|
await shutdown();
|
||||||
ipc.send('now-ready-for-shutdown');
|
ipc.send('now-ready-for-shutdown');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ipc.send(
|
ipc.send('now-ready-for-shutdown', Errors.toLogFormat(error));
|
||||||
'now-ready-for-shutdown',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ const port = parentPort;
|
||||||
function respond(uuid: string, error: Error | undefined, response?: File) {
|
function respond(uuid: string, error: Error | undefined, response?: File) {
|
||||||
const wrappedResponse: WrappedWorkerResponse = {
|
const wrappedResponse: WrappedWorkerResponse = {
|
||||||
uuid,
|
uuid,
|
||||||
error: error ? error.stack : undefined,
|
error: error?.stack,
|
||||||
response,
|
response,
|
||||||
};
|
};
|
||||||
port.postMessage(wrappedResponse);
|
port.postMessage(wrappedResponse);
|
||||||
|
|
Loading…
Reference in a new issue