Improve error handling during group sends
This commit is contained in:
parent
f0a3735ca2
commit
991580a1ed
58 changed files with 299 additions and 324 deletions
|
@ -575,7 +575,7 @@ export default class AccountManager extends EventTarget {
|
|||
} catch (error) {
|
||||
log.error(
|
||||
'Something went wrong deleting data from previous number',
|
||||
error && error.stack ? error.stack : error
|
||||
Errors.toLogFormat(error)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -8,6 +8,7 @@ import protobuf from '../protobuf/wrap';
|
|||
import { SignalService as Proto } from '../protobuf';
|
||||
import { normalizeUuid } from '../util/normalizeUuid';
|
||||
import { DurationInSeconds } from '../util/durations';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as log from '../logging/log';
|
||||
|
||||
import Avatar = Proto.ContactDetails.IAvatar;
|
||||
|
@ -90,10 +91,7 @@ abstract class ParserBase<
|
|||
expireTimer,
|
||||
};
|
||||
} catch (error) {
|
||||
log.error(
|
||||
'ProtoParser.next error:',
|
||||
error && error.stack ? error.stack : error
|
||||
);
|
||||
log.error('ProtoParser.next error:', Errors.toLogFormat(error));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,8 +54,9 @@ export class ReplayableError extends Error {
|
|||
name?: string;
|
||||
message: string;
|
||||
functionCode?: number;
|
||||
cause?: unknown;
|
||||
}) {
|
||||
super(options.message);
|
||||
super(options.message, { cause: options.cause });
|
||||
|
||||
this.name = options.name || 'ReplayableError';
|
||||
this.message = options.message;
|
||||
|
@ -71,7 +72,7 @@ export class ReplayableError extends Error {
|
|||
}
|
||||
|
||||
export class OutgoingIdentityKeyError extends ReplayableError {
|
||||
identifier: string;
|
||||
public readonly identifier: string;
|
||||
|
||||
// Note: Data to resend message is no longer captured
|
||||
constructor(incomingIdentifier: string) {
|
||||
|
@ -162,6 +163,7 @@ export class SendMessageChallengeError extends ReplayableError {
|
|||
super({
|
||||
name: 'SendMessageChallengeError',
|
||||
message: httpError.message,
|
||||
cause: httpError,
|
||||
});
|
||||
|
||||
[this.identifier] = identifier.split('.');
|
||||
|
@ -237,9 +239,7 @@ export class SendMessageProtoError extends Error implements CallbackResultType {
|
|||
return 'No errors';
|
||||
}
|
||||
|
||||
return errors
|
||||
.map(error => (error.stackForLog ? error.stackForLog : error.toString()))
|
||||
.join(', ');
|
||||
return errors.map(error => error.toString()).join(', ');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ import type {
|
|||
PlaintextContent,
|
||||
} from '@signalapp/libsignal-client';
|
||||
import {
|
||||
ErrorCode,
|
||||
LibSignalErrorBase,
|
||||
CiphertextMessageType,
|
||||
ProtocolAddress,
|
||||
sealedSenderEncrypt,
|
||||
|
@ -34,6 +36,7 @@ import {
|
|||
import type { CallbackResultType, CustomError } from './Types.d';
|
||||
import { isValidNumber } from '../types/PhoneNumber';
|
||||
import { Address } from '../types/Address';
|
||||
import * as Errors from '../types/errors';
|
||||
import { QualifiedAddress } from '../types/QualifiedAddress';
|
||||
import { UUID, isValidUuid } from '../types/UUID';
|
||||
import { Sessions, IdentityKeys } from '../LibSignalStores';
|
||||
|
@ -244,8 +247,7 @@ export default class OutgoingMessage {
|
|||
}
|
||||
}
|
||||
|
||||
error.reason = reason;
|
||||
error.stackForLog = providedError ? providedError.stack : undefined;
|
||||
error.cause = reason;
|
||||
|
||||
this.errors[this.errors.length] = error;
|
||||
this.numberCompleted();
|
||||
|
@ -284,21 +286,14 @@ export default class OutgoingMessage {
|
|||
: { accessKey: undefined };
|
||||
const { accessKey } = info;
|
||||
|
||||
try {
|
||||
const { accessKeyFailed } = await getKeysForIdentifier(
|
||||
identifier,
|
||||
this.server,
|
||||
updateDevices,
|
||||
accessKey
|
||||
);
|
||||
if (accessKeyFailed && !this.failoverIdentifiers.includes(identifier)) {
|
||||
this.failoverIdentifiers.push(identifier);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error?.message?.includes('untrusted identity for address')) {
|
||||
error.timestamp = this.timestamp;
|
||||
}
|
||||
throw error;
|
||||
const { accessKeyFailed } = await getKeysForIdentifier(
|
||||
identifier,
|
||||
this.server,
|
||||
updateDevices,
|
||||
accessKey
|
||||
);
|
||||
if (accessKeyFailed && !this.failoverIdentifiers.includes(identifier)) {
|
||||
this.failoverIdentifiers.push(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
'Got "key changed" error from encrypt - no identityKey for application layer',
|
||||
identifier,
|
||||
|
@ -643,7 +643,8 @@ export default class OutgoingMessage {
|
|||
},
|
||||
innerError => {
|
||||
log.error(
|
||||
`doSendMessage: Error closing sessions: ${innerError.stack}`
|
||||
'doSendMessage: Error closing sessions: ' +
|
||||
`${Errors.toLogFormat(innerError)}`
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
|
@ -653,7 +654,7 @@ export default class OutgoingMessage {
|
|||
this.registerError(
|
||||
identifier,
|
||||
'Failed to create or send message',
|
||||
error
|
||||
newError
|
||||
);
|
||||
|
||||
return undefined;
|
||||
|
@ -712,7 +713,7 @@ export default class OutgoingMessage {
|
|||
} catch (error) {
|
||||
log.error(
|
||||
`sendToIdentifier: Failed to fetch UUID for identifier ${identifier}`,
|
||||
error && error.stack ? error.stack : error
|
||||
Errors.toLogFormat(error)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
@ -731,7 +732,10 @@ export default class OutgoingMessage {
|
|||
}
|
||||
await this.reloadDevicesAndSend(identifier, true)();
|
||||
} catch (error) {
|
||||
if (error?.message?.includes('untrusted identity for address')) {
|
||||
if (
|
||||
error instanceof LibSignalErrorBase &&
|
||||
error.code === ErrorCode.UntrustedIdentity
|
||||
) {
|
||||
const newError = new OutgoingIdentityKeyError(identifier);
|
||||
this.registerError(identifier, 'Untrusted identity', newError);
|
||||
} else {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import {
|
||||
ErrorCode,
|
||||
LibSignalErrorBase,
|
||||
PreKeyBundle,
|
||||
processPreKeyBundle,
|
||||
ProtocolAddress,
|
||||
|
@ -9,9 +11,9 @@ import {
|
|||
} from '@signalapp/libsignal-client';
|
||||
|
||||
import {
|
||||
OutgoingIdentityKeyError,
|
||||
UnregisteredUserError,
|
||||
HTTPError,
|
||||
OutgoingIdentityKeyError,
|
||||
} from './Errors';
|
||||
import { Sessions, IdentityKeys } from '../LibSignalStores';
|
||||
import { Address } from '../types/Address';
|
||||
|
@ -72,13 +74,6 @@ async function getServerKeys(
|
|||
}),
|
||||
};
|
||||
} catch (error: unknown) {
|
||||
if (
|
||||
error instanceof Error &&
|
||||
error.message.includes('untrusted identity')
|
||||
) {
|
||||
throw new OutgoingIdentityKeyError(identifier);
|
||||
}
|
||||
|
||||
if (
|
||||
accessKey &&
|
||||
isRecord(error) &&
|
||||
|
@ -155,22 +150,27 @@ async function handleServerKeys(
|
|||
ourUuid,
|
||||
new Address(theirUuid, deviceId)
|
||||
);
|
||||
await window.textsecure.storage.protocol
|
||||
.enqueueSessionJob(address, () =>
|
||||
processPreKeyBundle(
|
||||
preKeyBundle,
|
||||
protocolAddress,
|
||||
sessionStore,
|
||||
identityKeyStore
|
||||
)
|
||||
)
|
||||
.catch(error => {
|
||||
if (error?.message?.includes('untrusted identity for address')) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
error.identityKey = response.identityKey;
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
|
||||
try {
|
||||
await window.textsecure.storage.protocol.enqueueSessionJob(
|
||||
address,
|
||||
() =>
|
||||
processPreKeyBundle(
|
||||
preKeyBundle,
|
||||
protocolAddress,
|
||||
sessionStore,
|
||||
identityKeyStore
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
if (
|
||||
error instanceof LibSignalErrorBase &&
|
||||
error.code === ErrorCode.UntrustedIdentity
|
||||
) {
|
||||
throw new OutgoingIdentityKeyError(identifier);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue