fix(translate): 修复翻译过程中中止控制器的错误处理

修正abortController.ts中中止控制器的回调函数调用方式
统一翻译错误消息的格式化处理
改进翻译服务的中止逻辑和错误传播
This commit is contained in:
icarus 2025-08-29 22:32:37 +08:00
parent 7a5050d2a2
commit e0f86688a2
3 changed files with 20 additions and 10 deletions

View File

@ -155,7 +155,7 @@ const TranslatePage: FC = () => {
} catch (e) { } catch (e) {
if (!isAbortError(e)) { if (!isAbortError(e)) {
logger.error('Failed to translate text', e as Error) 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) setTranslating(false)
return return
@ -167,11 +167,11 @@ const TranslatePage: FC = () => {
await saveTranslateHistory(text, translated, actualSourceLanguage.langCode, actualTargetLanguage.langCode) await saveTranslateHistory(text, translated, actualSourceLanguage.langCode, actualTargetLanguage.langCode)
} catch (e) { } catch (e) {
logger.error('Failed to save translate history', e as Error) 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) { } catch (e) {
logger.error('Failed to translate', e as Error) 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] [dispatch, setTranslatedContent, setTranslating, t, translating]

View File

@ -3,6 +3,7 @@ import { db } from '@renderer/databases'
import { CustomTranslateLanguage, TranslateHistory, TranslateLanguage, TranslateLanguageCode } from '@renderer/types' import { CustomTranslateLanguage, TranslateHistory, TranslateLanguage, TranslateLanguageCode } from '@renderer/types'
import { Chunk, ChunkType } from '@renderer/types/chunk' import { Chunk, ChunkType } from '@renderer/types/chunk'
import { uuid } from '@renderer/utils' import { uuid } from '@renderer/utils'
import { readyToAbort } from '@renderer/utils/abortController'
import { formatErrorMessage, isAbortError } from '@renderer/utils/error' import { formatErrorMessage, isAbortError } from '@renderer/utils/error'
import { t } from 'i18next' import { t } from 'i18next'
@ -70,14 +71,14 @@ const logger = loggerService.withContext('TranslateService')
export const translateText = async ( export const translateText = async (
text: string, text: string,
targetLanguage: TranslateLanguage, targetLanguage: TranslateLanguage,
onResponse?: (text: string, isComplete: boolean) => void onResponse?: (text: string, isComplete: boolean) => void,
// abortKey?: string abortKey?: string
) => { ) => {
let abortError
try { try {
const assistant = getDefaultTranslateAssistant(targetLanguage, text) const assistant = getDefaultTranslateAssistant(targetLanguage, text)
const controller = new AbortController() const signal = abortKey ? readyToAbort(abortKey) : undefined
const signal = controller.signal
let translatedText = '' let translatedText = ''
let completed = false let completed = false
@ -86,6 +87,11 @@ export const translateText = async (
translatedText = chunk.text translatedText = chunk.text
} else if (chunk.type === ChunkType.TEXT_COMPLETE) { } else if (chunk.type === ChunkType.TEXT_COMPLETE) {
completed = true completed = true
} else if (chunk.type === ChunkType.ERROR) {
if (isAbortError(chunk.error)) {
abortError = chunk.error
completed = true
}
} }
onResponse?.(translatedText, completed) onResponse?.(translatedText, completed)
} }
@ -95,7 +101,7 @@ export const translateText = async (
} satisfies FetchChatCompletionOptions } satisfies FetchChatCompletionOptions
await fetchChatCompletion({ await fetchChatCompletion({
prompt: 'translate it', prompt: assistant.content,
assistant, assistant,
options, options,
onChunkReceived: onChunk onChunkReceived: onChunk
@ -111,11 +117,15 @@ export const translateText = async (
} catch (e) { } catch (e) {
if (isAbortError(e)) { if (isAbortError(e)) {
window.message.info(t('translate.info.aborted')) window.message.info(t('translate.info.aborted'))
throw e
} else if (isAbortError(abortError)) {
window.message.info(t('translate.info.aborted'))
throw abortError
} else { } else {
logger.error('Failed to translate', e as Error) logger.error('Failed to translate', e as Error)
window.message.error(t('translate.error.failed' + ': ' + formatErrorMessage(e))) window.message.error(t('translate.error.failed' + ': ' + formatErrorMessage(e)))
throw e
} }
throw e
} }
} }

View File

@ -68,6 +68,6 @@ export function createAbortPromise<T>(signal: AbortSignal, finallyPromise: Promi
*/ */
export function readyToAbort(key: string) { export function readyToAbort(key: string) {
const controller = new AbortController() const controller = new AbortController()
addAbortController(key, controller.abort) addAbortController(key, () => controller.abort())
return controller.signal return controller.signal
} }