From 52d86e4601698c7a5f897d308ca42a82ddb70694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=81=E6=A0=91=E4=BA=BA?= Date: Mon, 22 May 2023 22:24:41 +0100 Subject: [PATCH] feat: friendly way to inform user there's an error (#12) --- src/decrypt-worker/util/DecryptError.ts | 18 +++++++++- src/decrypt-worker/worker/handler/decrypt.ts | 2 +- src/features/file-listing/FileError.tsx | 36 +++++++++++++++++++ src/features/file-listing/FileRow.tsx | 6 +++- .../__tests__/__fixture__/file-list.ts | 5 ++- src/features/file-listing/fileListingSlice.ts | 30 +++++++++++----- src/util/ConcurrentQueue.ts | 10 +++--- src/util/WorkerEventBus.ts | 11 ++++-- 8 files changed, 99 insertions(+), 19 deletions(-) create mode 100644 src/features/file-listing/FileError.tsx diff --git a/src/decrypt-worker/util/DecryptError.ts b/src/decrypt-worker/util/DecryptError.ts index 205f1dd..d141191 100644 --- a/src/decrypt-worker/util/DecryptError.ts +++ b/src/decrypt-worker/util/DecryptError.ts @@ -1 +1,17 @@ -export class UnsupportedSourceFile extends Error {} +export enum DecryptErrorType { + UNSUPPORTED_FILE = 'UNSUPPORTED_FILE', + UNKNOWN = 'UNKNOWN', +} + +export class DecryptError extends Error { + code = DecryptErrorType.UNKNOWN; + + toJSON() { + const { name, message, stack, code } = this; + return { name, message, stack, code }; + } +} + +export class UnsupportedSourceFile extends DecryptError { + code = DecryptErrorType.UNSUPPORTED_FILE; +} diff --git a/src/decrypt-worker/worker/handler/decrypt.ts b/src/decrypt-worker/worker/handler/decrypt.ts index 851e978..1fc6cf4 100644 --- a/src/decrypt-worker/worker/handler/decrypt.ts +++ b/src/decrypt-worker/worker/handler/decrypt.ts @@ -38,7 +38,7 @@ class DecryptCommandHandler { } } - throw new Error('could not decrypt file: no working decryptor found'); + throw new UnsupportedSourceFile('could not decrypt file: no working decryptor found'); } async decryptFile(crypto: CryptoBase) { diff --git a/src/features/file-listing/FileError.tsx b/src/features/file-listing/FileError.tsx new file mode 100644 index 0000000..1369eba --- /dev/null +++ b/src/features/file-listing/FileError.tsx @@ -0,0 +1,36 @@ +import { chakra, Box, Button, Collapse, Text, useDisclosure } from '@chakra-ui/react'; +import { DecryptErrorType } from '~/decrypt-worker/util/DecryptError'; + +export interface FileErrorProps { + error: null | string; + code: null | string; +} + +const errorMap = new Map([ + [DecryptErrorType.UNSUPPORTED_FILE, '尚未支持的文件格式'], +]); + +export function FileError({ error, code }: FileErrorProps) { + const { isOpen, onToggle } = useDisclosure(); + const errorSummary = errorMap.get(code) ?? '未知错误'; + + return ( + + + 解密错误:{errorSummary} + {error && ( + + )} + + {error && ( + + + {error} + + + )} + + ); +} diff --git a/src/features/file-listing/FileRow.tsx b/src/features/file-listing/FileRow.tsx index 91d60d4..c33764e 100644 --- a/src/features/file-listing/FileRow.tsx +++ b/src/features/file-listing/FileRow.tsx @@ -18,6 +18,7 @@ import { useAppDispatch } from '~/hooks'; import { AnimationDefinition } from 'framer-motion'; import { AlbumImage } from './AlbumImage'; import { SongMetadata } from './SongMetadata'; +import { FileError } from './FileError'; interface FileRowProps { id: string; @@ -73,7 +74,10 @@ export function FileRow({ id, file }: FileRowProps) { {metadata?.name ?? nameWithoutExt} - {isDecrypted && metadata && } + + {isDecrypted && metadata && } + {file.state === ProcessState.ERROR && } + {file.decrypted &&