Improve recovery from corrupted downloads
This commit is contained in:
parent
a46a4a67b9
commit
572849b9dd
3 changed files with 21 additions and 10 deletions
|
@ -19,6 +19,7 @@ import {
|
|||
ValidatingPassThrough,
|
||||
} from '@signalapp/libsignal-client/dist/incremental_mac';
|
||||
import type { ChunkSizeChoice } from '@signalapp/libsignal-client/dist/incremental_mac';
|
||||
import { isAbsolute } from 'path';
|
||||
|
||||
import * as log from './logging/log';
|
||||
import {
|
||||
|
@ -37,7 +38,7 @@ import { finalStream } from './util/finalStream';
|
|||
import { getIvAndDecipher } from './util/getIvAndDecipher';
|
||||
import { getMacAndUpdateHmac } from './util/getMacAndUpdateHmac';
|
||||
import { trimPadding } from './util/trimPadding';
|
||||
import { strictAssert } from './util/assert';
|
||||
import { assertDev, strictAssert } from './util/assert';
|
||||
import * as Errors from './types/errors';
|
||||
import { isNotNil } from './util/isNotNil';
|
||||
import { missingCaseError } from './util/missingCaseError';
|
||||
|
@ -733,11 +734,17 @@ export function getPlaintextHashForInMemoryAttachment(
|
|||
* Unlinks a file without throwing an error if it doesn't exist.
|
||||
* Throws an error if it fails to unlink for any other reason.
|
||||
*/
|
||||
export async function safeUnlink(filePath: string): Promise<void> {
|
||||
export async function safeUnlink(absoluteFilePath: string): Promise<void> {
|
||||
assertDev(
|
||||
isAbsolute(absoluteFilePath),
|
||||
'safeUnlink: a relative path was passed instead of an absolute one'
|
||||
);
|
||||
|
||||
try {
|
||||
await unlink(filePath);
|
||||
await unlink(absoluteFilePath);
|
||||
} catch (error) {
|
||||
// Ignore if file doesn't exist
|
||||
|
||||
if (error.code !== 'ENOENT') {
|
||||
log.error('Failed to unlink', error);
|
||||
throw error;
|
||||
|
|
|
@ -134,7 +134,9 @@ describe('utils/ensureAttachmentIsReencryptable', async () => {
|
|||
|
||||
after(async () => {
|
||||
if (path) {
|
||||
await safeUnlink(path);
|
||||
await safeUnlink(
|
||||
window.Signal.Migrations.getAbsoluteAttachmentPath(path)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -126,10 +126,12 @@ export async function downloadAttachment(
|
|||
let downloadResult: Awaited<ReturnType<typeof downloadToDisk>>;
|
||||
|
||||
let { downloadPath } = attachment;
|
||||
const absoluteDownloadPath = downloadPath
|
||||
? window.Signal.Migrations.getAbsoluteAttachmentPath(downloadPath)
|
||||
: undefined;
|
||||
let downloadOffset = 0;
|
||||
if (downloadPath) {
|
||||
const absoluteDownloadPath =
|
||||
window.Signal.Migrations.getAbsoluteDownloadsPath(downloadPath);
|
||||
|
||||
if (absoluteDownloadPath) {
|
||||
try {
|
||||
({ size: downloadOffset } = await stat(absoluteDownloadPath));
|
||||
} catch (error) {
|
||||
|
@ -139,7 +141,7 @@ export async function downloadAttachment(
|
|||
Errors.toLogFormat(error)
|
||||
);
|
||||
try {
|
||||
await safeUnlink(downloadPath);
|
||||
await safeUnlink(absoluteDownloadPath);
|
||||
} catch {
|
||||
downloadPath = undefined;
|
||||
}
|
||||
|
@ -148,9 +150,9 @@ export async function downloadAttachment(
|
|||
}
|
||||
|
||||
// Start over if we go over the size
|
||||
if (downloadOffset >= size && downloadPath) {
|
||||
if (downloadOffset >= size && absoluteDownloadPath) {
|
||||
log.warn('downloadAttachment: went over, retrying');
|
||||
await safeUnlink(downloadPath);
|
||||
await safeUnlink(absoluteDownloadPath);
|
||||
downloadOffset = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue