Browse Source

Rely on global uncaught handler to log

Manav Rathi 1 year ago
parent
commit
9cf57c847e
1 changed files with 146 additions and 164 deletions
  1. 146 164
      web/apps/photos/src/services/download/index.ts

+ 146 - 164
web/apps/photos/src/services/download/index.ts

@@ -271,185 +271,167 @@ class DownloadManagerImpl {
     private async downloadFile(
         file: EnteFile,
     ): Promise<ReadableStream<Uint8Array>> {
-        try {
-            log.info(`download attempted for fileID:${file.id}`);
-            const onDownloadProgress = this.trackDownloadProgress(
-                file.id,
-                file.info?.fileSize,
-            );
-            if (
-                file.metadata.fileType === FILE_TYPE.IMAGE ||
-                file.metadata.fileType === FILE_TYPE.LIVE_PHOTO
-            ) {
-                const key = file.id.toString();
-                const cachedBlob = await this.fileCache?.get(key);
-                let encryptedArrayBuffer = await cachedBlob?.arrayBuffer();
-                if (!encryptedArrayBuffer) {
-                    const array = await this.downloadClient.downloadFile(
-                        file,
-                        onDownloadProgress,
-                    );
-                    encryptedArrayBuffer = array.buffer;
-                    this.fileCache?.put2(key, new Blob([encryptedArrayBuffer]));
-                }
-                this.clearDownloadProgress(file.id);
-                try {
-                    const decrypted = await this.cryptoWorker.decryptFile(
-                        new Uint8Array(encryptedArrayBuffer),
-                        await this.cryptoWorker.fromB64(
-                            file.file.decryptionHeader,
-                        ),
-                        file.key,
+        log.info(`download attempted for file id ${file.id}`);
+
+        const onDownloadProgress = this.trackDownloadProgress(
+            file.id,
+            file.info?.fileSize,
+        );
+
+        const cacheKey = file.id.toString();
+
+        if (
+            file.metadata.fileType === FILE_TYPE.IMAGE ||
+            file.metadata.fileType === FILE_TYPE.LIVE_PHOTO
+        ) {
+            const cachedBlob = await this.fileCache?.get(cacheKey);
+            let encryptedArrayBuffer = await cachedBlob?.arrayBuffer();
+            if (!encryptedArrayBuffer) {
+                const array = await this.downloadClient.downloadFile(
+                    file,
+                    onDownloadProgress,
+                );
+                encryptedArrayBuffer = array.buffer;
+                this.fileCache?.put2(
+                    cacheKey,
+                    new Blob([encryptedArrayBuffer]),
+                );
+            }
+            this.clearDownloadProgress(file.id);
+            try {
+                const decrypted = await this.cryptoWorker.decryptFile(
+                    new Uint8Array(encryptedArrayBuffer),
+                    await this.cryptoWorker.fromB64(file.file.decryptionHeader),
+                    file.key,
+                );
+                return generateStreamFromArrayBuffer(decrypted);
+            } catch (e) {
+                if (e.message === CustomError.PROCESSING_FAILED) {
+                    log.error(
+                        `Failed to process file with fileID:${file.id}, localID: ${file.metadata.localID}, version: ${file.metadata.version}, deviceFolder:${file.metadata.deviceFolder}`,
+                        e,
                     );
-                    return generateStreamFromArrayBuffer(decrypted);
-                } catch (e) {
-                    if (e.message === CustomError.PROCESSING_FAILED) {
-                        log.error(
-                            `Failed to process file with fileID:${file.id}, localID: ${file.metadata.localID}, version: ${file.metadata.version}, deviceFolder:${file.metadata.deviceFolder}`,
-                            e,
-                        );
-                    }
-                    throw e;
                 }
+                throw e;
             }
+        }
 
-            let resp: Response = await this.getCachedFile(file);
-            if (!resp) {
-                resp = await this.downloadClient.downloadFileStream(file);
-                if (this.fileCache) {
-                    this.fileCache
-                        .put(file.id.toString(), resp.clone())
-                        .catch((e) => {
-                            log.error("file cache put failed", e);
-                        });
-                }
-            }
-            const reader = resp.body.getReader();
-
-            const contentLength = +resp.headers.get("Content-Length") ?? 0;
-            let downloadedBytes = 0;
-
-            const stream = new ReadableStream({
-                start: async (controller) => {
-                    try {
-                        const decryptionHeader =
-                            await this.cryptoWorker.fromB64(
-                                file.file.decryptionHeader,
-                            );
-                        const fileKey = await this.cryptoWorker.fromB64(
-                            file.key,
+        let resp: Response = await this.getCachedFile(file);
+        if (!resp) {
+            resp = await this.downloadClient.downloadFileStream(file);
+            this?.fileCache.put(cacheKey, resp.clone());
+        }
+        const reader = resp.body.getReader();
+
+        const contentLength = +resp.headers.get("Content-Length") ?? 0;
+        let downloadedBytes = 0;
+
+        const stream = new ReadableStream({
+            start: async (controller) => {
+                try {
+                    const decryptionHeader = await this.cryptoWorker.fromB64(
+                        file.file.decryptionHeader,
+                    );
+                    const fileKey = await this.cryptoWorker.fromB64(file.key);
+                    const { pullState, decryptionChunkSize } =
+                        await this.cryptoWorker.initChunkDecryption(
+                            decryptionHeader,
+                            fileKey,
                         );
-                        const { pullState, decryptionChunkSize } =
-                            await this.cryptoWorker.initChunkDecryption(
-                                decryptionHeader,
-                                fileKey,
-                            );
-                        let data = new Uint8Array();
-                        // The following function handles each data chunk
-                        const push = () => {
-                            // "done" is a Boolean and value a "Uint8Array"
-                            reader.read().then(async ({ done, value }) => {
-                                try {
-                                    // Is there more data to read?
-                                    if (!done) {
-                                        downloadedBytes += value.byteLength;
-                                        onDownloadProgress({
-                                            loaded: downloadedBytes,
-                                            total: contentLength,
-                                        });
-                                        const buffer = new Uint8Array(
-                                            data.byteLength + value.byteLength,
-                                        );
-                                        buffer.set(new Uint8Array(data), 0);
-                                        buffer.set(
-                                            new Uint8Array(value),
-                                            data.byteLength,
+                    let data = new Uint8Array();
+                    // The following function handles each data chunk
+                    const push = () => {
+                        // "done" is a Boolean and value a "Uint8Array"
+                        reader.read().then(async ({ done, value }) => {
+                            try {
+                                // Is there more data to read?
+                                if (!done) {
+                                    downloadedBytes += value.byteLength;
+                                    onDownloadProgress({
+                                        loaded: downloadedBytes,
+                                        total: contentLength,
+                                    });
+                                    const buffer = new Uint8Array(
+                                        data.byteLength + value.byteLength,
+                                    );
+                                    buffer.set(new Uint8Array(data), 0);
+                                    buffer.set(
+                                        new Uint8Array(value),
+                                        data.byteLength,
+                                    );
+                                    if (buffer.length > decryptionChunkSize) {
+                                        const fileData = buffer.slice(
+                                            0,
+                                            decryptionChunkSize,
                                         );
-                                        if (
-                                            buffer.length > decryptionChunkSize
-                                        ) {
-                                            const fileData = buffer.slice(
-                                                0,
-                                                decryptionChunkSize,
-                                            );
-                                            try {
-                                                const { decryptedData } =
-                                                    await this.cryptoWorker.decryptFileChunk(
-                                                        fileData,
-                                                        pullState,
-                                                    );
-                                                controller.enqueue(
-                                                    decryptedData,
+                                        try {
+                                            const { decryptedData } =
+                                                await this.cryptoWorker.decryptFileChunk(
+                                                    fileData,
+                                                    pullState,
+                                                );
+                                            controller.enqueue(decryptedData);
+                                            data =
+                                                buffer.slice(
+                                                    decryptionChunkSize,
+                                                );
+                                        } catch (e) {
+                                            if (
+                                                e.message ===
+                                                CustomError.PROCESSING_FAILED
+                                            ) {
+                                                log.error(
+                                                    `Failed to process file ${file.id} from localID: ${file.metadata.localID} version: ${file.metadata.version} deviceFolder:${file.metadata.deviceFolder}`,
+                                                    e,
                                                 );
-                                                data =
-                                                    buffer.slice(
-                                                        decryptionChunkSize,
-                                                    );
-                                            } catch (e) {
-                                                if (
-                                                    e.message ===
-                                                    CustomError.PROCESSING_FAILED
-                                                ) {
-                                                    log.error(
-                                                        `Failed to process file ${file.id} from localID: ${file.metadata.localID} version: ${file.metadata.version} deviceFolder:${file.metadata.deviceFolder}`,
-                                                        e,
-                                                    );
-                                                }
-                                                throw e;
                                             }
-                                        } else {
-                                            data = buffer;
+                                            throw e;
                                         }
-                                        push();
                                     } else {
-                                        if (data) {
-                                            try {
-                                                const { decryptedData } =
-                                                    await this.cryptoWorker.decryptFileChunk(
-                                                        data,
-                                                        pullState,
-                                                    );
-                                                controller.enqueue(
-                                                    decryptedData,
+                                        data = buffer;
+                                    }
+                                    push();
+                                } else {
+                                    if (data) {
+                                        try {
+                                            const { decryptedData } =
+                                                await this.cryptoWorker.decryptFileChunk(
+                                                    data,
+                                                    pullState,
+                                                );
+                                            controller.enqueue(decryptedData);
+                                            data = null;
+                                        } catch (e) {
+                                            if (
+                                                e.message ===
+                                                CustomError.PROCESSING_FAILED
+                                            ) {
+                                                log.error(
+                                                    `Failed to process file ${file.id} from localID: ${file.metadata.localID} version: ${file.metadata.version} deviceFolder:${file.metadata.deviceFolder}`,
+                                                    e,
                                                 );
-                                                data = null;
-                                            } catch (e) {
-                                                if (
-                                                    e.message ===
-                                                    CustomError.PROCESSING_FAILED
-                                                ) {
-                                                    log.error(
-                                                        `Failed to process file ${file.id} from localID: ${file.metadata.localID} version: ${file.metadata.version} deviceFolder:${file.metadata.deviceFolder}`,
-                                                        e,
-                                                    );
-                                                }
-                                                throw e;
                                             }
+                                            throw e;
                                         }
-                                        controller.close();
                                     }
-                                } catch (e) {
-                                    log.error(
-                                        "Failed to process file chunk",
-                                        e,
-                                    );
-                                    controller.error(e);
+                                    controller.close();
                                 }
-                            });
-                        };
-
-                        push();
-                    } catch (e) {
-                        log.error("Failed to process file stream", e);
-                        controller.error(e);
-                    }
-                },
-            });
-            return stream;
-        } catch (e) {
-            log.error("Failed to download file", e);
-            throw e;
-        }
+                            } catch (e) {
+                                log.error("Failed to process file chunk", e);
+                                controller.error(e);
+                            }
+                        });
+                    };
+
+                    push();
+                } catch (e) {
+                    log.error("Failed to process file stream", e);
+                    controller.error(e);
+                }
+            },
+        });
+
+        return stream;
     }
 
     trackDownloadProgress = (fileID: number, fileSize: number) => {