From 839a935f423ef6ee42ea22040cc05731a837b9ac Mon Sep 17 00:00:00 2001 From: Abhinav-grd Date: Mon, 24 May 2021 10:19:27 +0530 Subject: [PATCH] imporve thumbnial generation fail handling --- src/pages/gallery/components/Upload.tsx | 2 +- src/services/uploadService.ts | 142 ++++++++++++------------ src/utils/common/errorUtil.ts | 2 + 3 files changed, 72 insertions(+), 74 deletions(-) diff --git a/src/pages/gallery/components/Upload.tsx b/src/pages/gallery/components/Upload.tsx index 2fb53b612..7157d7126 100644 --- a/src/pages/gallery/components/Upload.tsx +++ b/src/pages/gallery/components/Upload.tsx @@ -189,9 +189,9 @@ export default function Upload(props: Props) { ); } catch (err) { props.setBannerMessage(err.message); + setProgressView(false); throw err; } finally { - setProgressView(false); props.syncWithRemote(); } }; diff --git a/src/services/uploadService.ts b/src/services/uploadService.ts index 327e75d65..32a0cf76c 100644 --- a/src/services/uploadService.ts +++ b/src/services/uploadService.ts @@ -5,7 +5,10 @@ import { File, fileAttribute } from './fileService'; import { Collection } from './collectionService'; import { FILE_TYPE } from 'pages/gallery'; import { checkConnectivity, WaitFor2Seconds } from 'utils/common'; -import { ErrorHandler } from 'utils/common/errorUtil'; +import { + ErrorHandler, + THUMBNAIL_GENERATION_FAILED, +} from 'utils/common/errorUtil'; import { getDedicatedCryptoWorker } from 'utils/crypto'; import * as convert from 'xml-js'; import { ENCRYPTION_CHUNK_SIZE } from 'types'; @@ -160,9 +163,8 @@ class UploadService { this.uploadErrors = []; this.metadataMap = new Map(); this.progressBarProps = progressBarProps; - this.existingFilesCollectionWise = sortFilesIntoCollections( - existingFiles - ); + this.existingFilesCollectionWise = + sortFilesIntoCollections(existingFiles); this.updateProgressBarUI(); let metadataFiles: globalThis.File[] = []; @@ -254,14 +256,8 @@ class UploadService { this.fileProgress.delete(rawFile.name); return; } - let { - file: encryptedFile, - fileKey: encryptedKey, - }: EncryptedFile = await this.encryptFile( - worker, - file, - collection.key - ); + let { file: encryptedFile, fileKey: encryptedKey }: EncryptedFile = + await this.encryptFile(worker, file, collection.key); let backupedFile: BackupedFile = await this.uploadToBucket( encryptedFile ); @@ -300,11 +296,8 @@ class UploadService { } private updateProgressBarUI() { - const { - setPercentComplete, - setFileCounter, - setFileProgress, - } = this.progressBarProps; + const { setPercentComplete, setFileCounter, setFileProgress } = + this.progressBarProps; setFileCounter({ finished: this.filesCompleted, total: this.totalFileCount, @@ -424,25 +417,15 @@ class UploadService { encryptionKey: string ): Promise { try { - const { - key: fileKey, - file: encryptedFiledata, - }: EncryptionResult = isDataStream(file.filedata) - ? await this.encryptFileStream(worker, file.filedata) - : await worker.encryptFile(file.filedata); + const { key: fileKey, file: encryptedFiledata }: EncryptionResult = + isDataStream(file.filedata) + ? await this.encryptFileStream(worker, file.filedata) + : await worker.encryptFile(file.filedata); - const { - file: encryptedThumbnail, - }: EncryptionResult = await worker.encryptThumbnail( - file.thumbnail, - fileKey - ); - const { - file: encryptedMetadata, - }: EncryptionResult = await worker.encryptMetadata( - file.metadata, - fileKey - ); + const { file: encryptedThumbnail }: EncryptionResult = + await worker.encryptThumbnail(file.thumbnail, fileKey); + const { file: encryptedMetadata }: EncryptionResult = + await worker.encryptMetadata(file.metadata, fileKey); const encryptedKey: B64EncryptionResult = await worker.encryptToB64( fileKey, @@ -468,11 +451,8 @@ class UploadService { private async encryptFileStream(worker, fileData: DataStream) { const { stream, chunkCount } = fileData; const fileStreamReader = stream.getReader(); - const { - key, - decryptionHeader, - pushState, - } = await worker.initChunkEncryption(); + const { key, decryptionHeader, pushState } = + await worker.initChunkEncryption(); let ref = { pullCount: 1 }; const encryptedFileStream = new ReadableStream({ async pull(controller) { @@ -664,22 +644,31 @@ class UploadService { image.setAttribute('src', imageURL); await new Promise((resolve, reject) => { image.onload = () => { - const thumbnailWidth = - (image.width * THUMBNAIL_HEIGHT) / image.height; - canvas.width = thumbnailWidth; - canvas.height = THUMBNAIL_HEIGHT; - canvas_CTX.drawImage( - image, - 0, - 0, - thumbnailWidth, - THUMBNAIL_HEIGHT - ); - image = undefined; - resolve(null); + try { + const thumbnailWidth = + (image.width * THUMBNAIL_HEIGHT) / image.height; + canvas.width = thumbnailWidth; + canvas.height = THUMBNAIL_HEIGHT; + canvas_CTX.drawImage( + image, + 0, + 0, + thumbnailWidth, + THUMBNAIL_HEIGHT + ); + image = undefined; + resolve(null); + } catch (e) { + console.error(e); + reject(`${THUMBNAIL_GENERATION_FAILED} err: ${e}`); + } }; setTimeout( - () => reject(null), + () => + reject( + `${THUMBNAIL_GENERATION_FAILED} err: + wait time exceeded` + ), WAIT_TIME_THUMBNAIL_GENERATION ); }); @@ -688,26 +677,35 @@ class UploadService { let video = document.createElement('video'); imageURL = URL.createObjectURL(file); video.addEventListener('timeupdate', function () { - const thumbnailWidth = - (video.videoWidth * THUMBNAIL_HEIGHT) / - video.videoHeight; - canvas.width = thumbnailWidth; - canvas.height = THUMBNAIL_HEIGHT; - canvas_CTX.drawImage( - video, - 0, - 0, - thumbnailWidth, - THUMBNAIL_HEIGHT - ); - video = null; - resolve(null); + try { + const thumbnailWidth = + (video.videoWidth * THUMBNAIL_HEIGHT) / + video.videoHeight; + canvas.width = thumbnailWidth; + canvas.height = THUMBNAIL_HEIGHT; + canvas_CTX.drawImage( + video, + 0, + 0, + thumbnailWidth, + THUMBNAIL_HEIGHT + ); + video = null; + resolve(null); + } catch (e) { + console.error(e); + reject(`${THUMBNAIL_GENERATION_FAILED} err: ${e}`); + } }); video.preload = 'metadata'; video.src = imageURL; video.currentTime = 3; setTimeout( - () => reject(null), + () => + reject( + `${THUMBNAIL_GENERATION_FAILED} err: + wait time exceeded` + ), WAIT_TIME_THUMBNAIL_GENERATION ); }); @@ -895,10 +893,8 @@ class UploadService { ] of multipartUploadURLs.partURLs.entries()) { let combinedChunks = []; for (let i = 0; i < CHUNKS_COMBINED_FOR_UPLOAD; i++) { - let { - done, - value: chunk, - } = await streamEncryptedFileReader.read(); + let { done, value: chunk } = + await streamEncryptedFileReader.read(); if (done) { break; } diff --git a/src/utils/common/errorUtil.ts b/src/utils/common/errorUtil.ts index 15668127a..04d472d64 100644 --- a/src/utils/common/errorUtil.ts +++ b/src/utils/common/errorUtil.ts @@ -13,6 +13,8 @@ const AXIOS_NETWORK_ERROR = 'Network Error'; export const SUBSCRIPTION_VERIFICATION_ERROR = 'Subscription verification failed'; +export const THUMBNAIL_GENERATION_FAILED = 'thumbnail generation failed'; + export function ErrorHandler(error) { let errorMessage = null; if (error?.status) {