diff --git a/src/apis/index.js b/src/apis/index.js index adc32b8..bec664a 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -378,14 +378,14 @@ export const apiBuiltinAIDetect = async (text) => { * @param {*} param0 * @returns */ -const apiBuiltinAITranslate = ({ text, from, to, apiSetting }) => { +const apiBuiltinAITranslate = async ({ text, from, to, apiSetting }) => { if (!isBuiltinAIAvailable) { return ["", true]; } const { fetchInterval, fetchLimit, httpTimeout } = apiSetting; const fetchPool = getFetchPool(fetchInterval, fetchLimit); - return withTimeout( + const result = await withTimeout( fetchPool.push(fnPolyfill, { fn: chromeTranslate, msg: MSG_BUILTINAI_TRANSLATE, @@ -395,6 +395,17 @@ const apiBuiltinAITranslate = ({ text, from, to, apiSetting }) => { }), httpTimeout ); + + if (!result) { + throw new Error("apiBuiltinAITranslate got null reault"); + } + + const [trText, srLang, error] = result; + if (error) { + throw new Error("apiBuiltinAITranslate got error", error); + } + + return [trText, srLang]; }; /** @@ -438,17 +449,16 @@ export const apiTranslate = async ({ // 查询缓存数据 if (useCache) { - const cache = (await getHttpCachePolyfill(cacheInput)) || {}; - if (cache.trText) { + const cache = await getHttpCachePolyfill(cacheInput); + if (cache?.trText) { return [cache.trText, cache.isSame]; } } // 请求接口数据 - let trText = ""; - let srLang = ""; + let tranlation = []; if (apiType === OPT_TRANS_BUILTINAI) { - [trText, srLang] = await apiBuiltinAITranslate({ + tranlation = await apiBuiltinAITranslate({ text, from, to, @@ -462,7 +472,7 @@ export const apiTranslate = async ({ batchSize, batchLength, }); - const tranlation = await queue.addTask(text, { + tranlation = await queue.addTask(text, { from, to, fromLang, @@ -473,13 +483,8 @@ export const apiTranslate = async ({ apiSetting, usePool, }); - if (Array.isArray(tranlation)) { - [trText, srLang = ""] = tranlation; - } else if (typeof tranlation === "string") { - trText = tranlation; - } } else { - const translations = await handleTranslate([text], { + [tranlation] = await handleTranslate([text], { from, to, fromLang, @@ -490,19 +495,24 @@ export const apiTranslate = async ({ apiSetting, usePool, }); - if (Array.isArray(translations)) { - if (Array.isArray(translations[0])) { - [trText, srLang = ""] = translations[0]; - } else { - [trText, srLang = ""] = translations; - } - } + } + + let trText = ""; + let srLang = ""; + if (Array.isArray(tranlation)) { + [trText, srLang = ""] = tranlation; + } else if (typeof tranlation === "string") { + trText = tranlation; + } + + if (!trText) { + throw new Error("tanslate api got empty trtext"); } const isSame = fromLang === "auto" && srLang === to; // 插入缓存 - if (useCache && trText) { + if (useCache) { putHttpCachePolyfill(cacheInput, null, { trText, isSame, srLang }); } diff --git a/src/apis/trans.js b/src/apis/trans.js index 6bed895..02614a6 100644 --- a/src/apis/trans.js +++ b/src/apis/trans.js @@ -745,6 +745,7 @@ export const parseTransRes = async ( let modelMsg = ""; + // todo: 根据结果抛出实际异常信息 switch (apiType) { case OPT_TRANS_GOOGLE: return [[res?.sentences?.map((item) => item.trans).join(" "), res?.src]]; @@ -842,7 +843,7 @@ export const parseTransRes = async ( default: } - return []; + throw new Error("parse translate result: apiType not matched", apiType); }; /** @@ -883,6 +884,9 @@ export const handleTranslate = async ( let token = ""; if (apiType === OPT_TRANS_MICROSOFT) { token = await msAuth(); + if (!token) { + throw new Error("got msauth error"); + } } const [input, init, userMsg] = await genTransReq({ @@ -899,19 +903,18 @@ export const handleTranslate = async ( ...apiSetting, }); - const res = await fetchData(input, init, { + const response = await fetchData(input, init, { useCache: false, usePool, fetchInterval, fetchLimit, httpTimeout, }); - if (!res) { - kissLog("tranlate got empty response"); - return []; + if (!response) { + throw new Error("tranlate got empty response"); } - return parseTransRes(res, { + const result = await parseTransRes(response, { texts, from, to, @@ -922,6 +925,11 @@ export const handleTranslate = async ( userMsg, ...apiSetting, }); + if (!Array.isArray(result)) { + throw new Error("tranlate got an unexpected result"); + } + + return result; }; /** diff --git a/src/libs/cache.js b/src/libs/cache.js index ce9c43c..538980d 100644 --- a/src/libs/cache.js +++ b/src/libs/cache.js @@ -47,11 +47,12 @@ const newCacheReq = async (input, init) => { */ export const getHttpCache = async ({ input, init }) => { try { - const req = await newCacheReq(input, init); + const request = await newCacheReq(input, init); const cache = await caches.open(CACHE_NAME); - const res = await cache.match(req); - if (res) { - return await parseResponse(res); + const response = await cache.match(request); + if (response) { + const res = await parseResponse(response); + return res; } } catch (err) { kissLog("get cache", err); diff --git a/src/libs/translator.js b/src/libs/translator.js index d3521bb..c35f203 100644 --- a/src/libs/translator.js +++ b/src/libs/translator.js @@ -970,6 +970,7 @@ export class Translator { // langDetector, } = this.#setting; const parentNode = hostNode.parentElement; + const hideOrigin = transOnly === "true"; // 翻译开始钩子函数 if (transStartHook?.trim()) { @@ -985,49 +986,37 @@ export class Translator { } } - const [processedString, placeholderMap] = - this.#serializeForTranslation(nodes); - // console.log("processedString", processedString); - if (this.#isInvalidText(processedString)) return; - - const wrapper = document.createElement(this.#translationTagName); - wrapper.className = Translator.KISS_CLASS.warpper; - - if (processedString.length > newlineLength) { - const br = document.createElement("br"); - br.hidden = transOnly === "true"; - wrapper.appendChild(br); - } - - const inner = document.createElement(transTag); - inner.className = `${Translator.KISS_CLASS.inner} ${this.#textClass[textStyle]}`; - inner.appendChild(createLoadingSVG()); - wrapper.appendChild(inner); - nodes[nodes.length - 1].after(wrapper); - - this.#translationNodes.set(wrapper, { - nodes, - isHide: transOnly === "true", - }); - const currentRunId = this.#runId; - try { - // const deLang = await tryDetectLang( - // processedString, - // detectRemote, - // langDetector - // ); - // if (deLang && (toLang.includes(deLang) || skipLangs.includes(deLang))) { - // wrapper.remove(); - // return; - // } + const [processedString, placeholderMap] = + this.#serializeForTranslation(nodes); + // console.log("processedString", processedString); + if (this.#isInvalidText(processedString)) return; + const wrapper = document.createElement(this.#translationTagName); + wrapper.className = Translator.KISS_CLASS.warpper; + + if (processedString.length > newlineLength) { + const br = document.createElement("br"); + br.hidden = hideOrigin; + wrapper.appendChild(br); + } + + const inner = document.createElement(transTag); + inner.className = `${Translator.KISS_CLASS.inner} ${this.#textClass[textStyle]}`; + inner.appendChild(createLoadingSVG()); + wrapper.appendChild(inner); + nodes[nodes.length - 1].after(wrapper); + + const currentRunId = this.#runId; const [translatedText, isSameLang] = await this.#translateFetch( processedString, deLang ); - // console.log("translatedText", translatedText); - if (isSameLang || this.#runId !== currentRunId) { + if (this.#runId !== currentRunId) { + throw new Error("Request terminated"); + } + + if (!translatedText || isSameLang) { wrapper.remove(); return; } @@ -1036,7 +1025,11 @@ export class Translator { translatedText, placeholderMap ); - if (transOnly === "true") { + this.#translationNodes.set(wrapper, { + nodes, + isHide: hideOrigin, + }); + if (hideOrigin) { this.#removeNodes(nodes); } @@ -1069,8 +1062,8 @@ export class Translator { } catch (err) { // inner.textContent = `[失败]...`; // todo: 失败重试按钮 - wrapper.remove(); - kissLog("translateNodeGroup", err); + kissLog("translate group error: ", err.message); + this.#cleanupDirectTranslations(hostNode); } }