From e0f86688a272b4dbdd5ab6e48060bf7403f5f562 Mon Sep 17 00:00:00 2001 From: icarus Date: Fri, 29 Aug 2025 22:32:37 +0800 Subject: [PATCH] =?UTF-8?q?fix(translate):=20=E4=BF=AE=E5=A4=8D=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=E8=BF=87=E7=A8=8B=E4=B8=AD=E4=B8=AD=E6=AD=A2=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E7=9A=84=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正abortController.ts中中止控制器的回调函数调用方式 统一翻译错误消息的格式化处理 改进翻译服务的中止逻辑和错误传播 --- .../src/pages/translate/TranslatePage.tsx | 6 ++--- src/renderer/src/services/TranslateService.ts | 22 ++++++++++++++----- src/renderer/src/utils/abortController.ts | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/renderer/src/pages/translate/TranslatePage.tsx b/src/renderer/src/pages/translate/TranslatePage.tsx index cf1e8c5335..71d58765a7 100644 --- a/src/renderer/src/pages/translate/TranslatePage.tsx +++ b/src/renderer/src/pages/translate/TranslatePage.tsx @@ -155,7 +155,7 @@ const TranslatePage: FC = () => { } catch (e) { if (!isAbortError(e)) { logger.error('Failed to translate text', e as Error) - window.message.error(t('translate.error.failed' + ': ' + (e as Error).message)) + window.message.error(t('translate.error.failed') + ': ' + formatErrorMessage(e)) } setTranslating(false) return @@ -167,11 +167,11 @@ const TranslatePage: FC = () => { await saveTranslateHistory(text, translated, actualSourceLanguage.langCode, actualTargetLanguage.langCode) } catch (e) { logger.error('Failed to save translate history', e as Error) - window.message.error(t('translate.history.error.save') + ': ' + (e as Error).message) + window.message.error(t('translate.history.error.save') + ': ' + formatErrorMessage(e)) } } catch (e) { logger.error('Failed to translate', e as Error) - window.message.error(t('translate.error.unknown') + ': ' + (e as Error).message) + window.message.error(t('translate.error.unknown') + ': ' + formatErrorMessage(e)) } }, [dispatch, setTranslatedContent, setTranslating, t, translating] diff --git a/src/renderer/src/services/TranslateService.ts b/src/renderer/src/services/TranslateService.ts index cda08a493f..f84edffcd4 100644 --- a/src/renderer/src/services/TranslateService.ts +++ b/src/renderer/src/services/TranslateService.ts @@ -3,6 +3,7 @@ import { db } from '@renderer/databases' import { CustomTranslateLanguage, TranslateHistory, TranslateLanguage, TranslateLanguageCode } from '@renderer/types' import { Chunk, ChunkType } from '@renderer/types/chunk' import { uuid } from '@renderer/utils' +import { readyToAbort } from '@renderer/utils/abortController' import { formatErrorMessage, isAbortError } from '@renderer/utils/error' import { t } from 'i18next' @@ -70,14 +71,14 @@ const logger = loggerService.withContext('TranslateService') export const translateText = async ( text: string, targetLanguage: TranslateLanguage, - onResponse?: (text: string, isComplete: boolean) => void - // abortKey?: string + onResponse?: (text: string, isComplete: boolean) => void, + abortKey?: string ) => { + let abortError try { const assistant = getDefaultTranslateAssistant(targetLanguage, text) - const controller = new AbortController() - const signal = controller.signal + const signal = abortKey ? readyToAbort(abortKey) : undefined let translatedText = '' let completed = false @@ -86,6 +87,11 @@ export const translateText = async ( translatedText = chunk.text } else if (chunk.type === ChunkType.TEXT_COMPLETE) { completed = true + } else if (chunk.type === ChunkType.ERROR) { + if (isAbortError(chunk.error)) { + abortError = chunk.error + completed = true + } } onResponse?.(translatedText, completed) } @@ -95,7 +101,7 @@ export const translateText = async ( } satisfies FetchChatCompletionOptions await fetchChatCompletion({ - prompt: 'translate it', + prompt: assistant.content, assistant, options, onChunkReceived: onChunk @@ -111,11 +117,15 @@ export const translateText = async ( } catch (e) { if (isAbortError(e)) { window.message.info(t('translate.info.aborted')) + throw e + } else if (isAbortError(abortError)) { + window.message.info(t('translate.info.aborted')) + throw abortError } else { logger.error('Failed to translate', e as Error) window.message.error(t('translate.error.failed' + ': ' + formatErrorMessage(e))) + throw e } - throw e } } diff --git a/src/renderer/src/utils/abortController.ts b/src/renderer/src/utils/abortController.ts index 614b7b068f..11bd7a791d 100644 --- a/src/renderer/src/utils/abortController.ts +++ b/src/renderer/src/utils/abortController.ts @@ -68,6 +68,6 @@ export function createAbortPromise(signal: AbortSignal, finallyPromise: Promi */ export function readyToAbort(key: string) { const controller = new AbortController() - addAbortController(key, controller.abort) + addAbortController(key, () => controller.abort()) return controller.signal }