From 2073caf3835401efdd87e6bb4b0edafa4ec4451c Mon Sep 17 00:00:00 2001 From: alger Date: Sun, 5 Jul 2026 19:53:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(main):=20=E4=BF=AE=E5=A4=8D=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E8=BF=87=E6=9C=9F=E6=97=A0=E6=B3=95=E6=81=A2=E5=A4=8D?= =?UTF-8?q?=E3=80=81=E9=85=8D=E7=BD=AE=E5=86=99=E6=94=BE=E5=A4=A7=E3=80=81?= =?UTF-8?q?=E4=B8=BB=E8=BF=9B=E7=A8=8B=20i18n=20=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - downloadManager: axios 放行 403/410,让直链过期能触发重新解析(修复重启恢复队列时下载失效) - cache: getCacheConfig 纯读不再落盘 config.json,消除播放/下载热路径的写放大与文件争用 - i18n/main: 未知/非法 locale 回退默认语言并加空值防护,避免托盘/登录窗构建时崩溃 - lxMusicHttp: 超时定时器在 fetch 出错路径也清理 - loginWindow: 标题改为打开窗口时求值,跟随当前语言 --- src/i18n/main.ts | 8 ++++++-- src/main/modules/cache.ts | 4 +++- src/main/modules/downloadManager.ts | 8 +++++++- src/main/modules/loginWindow.ts | 4 ++-- src/main/modules/lxMusicHttp.ts | 10 ++++++++-- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/i18n/main.ts b/src/i18n/main.ts index 129dca8..eb62d70 100644 --- a/src/i18n/main.ts +++ b/src/i18n/main.ts @@ -18,9 +18,13 @@ const mainI18n = { }, t(key: string) { const keys = key.split('.'); - let current: any = messages[this.currentLocale]; + // 未知/非法 locale 时回退默认语言,避免 messages[locale] 为 undefined 导致崩溃 + let current: any = messages[this.currentLocale] ?? messages[DEFAULT_LANGUAGE as Language]; + if (current == null) { + return key; + } for (const k of keys) { - if (current[k] === undefined) { + if (current == null || current[k] === undefined) { // 如果找不到翻译,返回键名 return key; } diff --git a/src/main/modules/cache.ts b/src/main/modules/cache.ts index f45a07c..4dee06b 100644 --- a/src/main/modules/cache.ts +++ b/src/main/modules/cache.ts @@ -413,7 +413,9 @@ class DiskCacheManager { cleanupPolicy }; - this.saveConfig(normalizedConfig); + // 注意:getCacheConfig 是纯读取,处于播放/下载/歌词等多个热路径。 + // 此处不再落盘(electron-store.set 每次整文件写 config.json,会造成写放大与文件争用), + // 持久化交由 updateCacheConfig / setCacheDirectory 等真正的写操作完成。 return normalizedConfig; } diff --git a/src/main/modules/downloadManager.ts b/src/main/modules/downloadManager.ts index 5373bb9..1f960e0 100644 --- a/src/main/modules/downloadManager.ts +++ b/src/main/modules/downloadManager.ts @@ -484,13 +484,17 @@ class DownloadManager { } // Start download + // 注意:axios 默认只接受 2xx,403/410 会直接抛错进入 catch,导致下方"直链过期重新解析" + // 分支永远走不到。这里放行 403/410,让过期直链能触发重新解析(尤其是重启后恢复队列时)。 const response = await axios({ url: task.url, method: 'GET', responseType: 'stream', timeout: 30000, signal: controller.signal, - headers + headers, + validateStatus: (status) => + (status >= 200 && status < 300) || status === 403 || status === 410 }); // Handle response status @@ -498,6 +502,8 @@ class DownloadManager { if (status === 403 || status === 410) { // URL expired, request re-resolution from renderer + // 排空未消费的错误响应流,避免连接悬挂 + response.data?.destroy?.(); this.sendToRenderer('download:request-url', { taskId: task.taskId, songInfo: task.songInfo diff --git a/src/main/modules/loginWindow.ts b/src/main/modules/loginWindow.ts index 58b6afd..6bf63ae 100644 --- a/src/main/modules/loginWindow.ts +++ b/src/main/modules/loginWindow.ts @@ -6,7 +6,6 @@ import i18n from '../../i18n/main'; let loginWindow: BrowserWindow | null = null; const loginUrl = 'https://music.163.com/#/login/'; -const loginTitle = i18n.global.t('login.qrTitle'); /** * 打开登录窗口获取Cookie @@ -29,7 +28,8 @@ const openLoginWindow = async (mainWin: BrowserWindow) => { loginWindow = new BrowserWindow({ parent: mainWin, - title: loginTitle, + // 在打开窗口时求值,确保跟随当前语言(模块加载时 i18n locale 可能尚未设置) + title: i18n.global.t('login.qrTitle'), width: 1280, height: 800, center: true, diff --git a/src/main/modules/lxMusicHttp.ts b/src/main/modules/lxMusicHttp.ts index 2dd1842..bcd713d 100644 --- a/src/main/modules/lxMusicHttp.ts +++ b/src/main/modules/lxMusicHttp.ts @@ -42,6 +42,8 @@ export const initLxMusicHttp = () => { // 保存取消控制器 abortControllers.set(requestId, controller); + let timeoutId: ReturnType | null = null; + try { console.log(`[LxMusicHttp] 请求: ${options.method || 'GET'} ${url}`); @@ -77,13 +79,14 @@ export const initLxMusicHttp = () => { // 设置超时 const timeout = options.timeout || 30000; - const timeoutId = setTimeout(() => { + timeoutId = setTimeout(() => { console.warn(`[LxMusicHttp] 请求超时: ${url}`); controller.abort(); }, timeout); const response = await fetch(url, fetchOptions); clearTimeout(timeoutId); + timeoutId = null; console.log(`[LxMusicHttp] 响应: ${response.status} ${url}`); @@ -122,7 +125,10 @@ export const initLxMusicHttp = () => { console.error(`[LxMusicHttp] 请求失败: ${url}`, error.message); throw error; } finally { - // 清理取消控制器 + // 清理超时定时器(fetch 出错时前面来不及 clear)与取消控制器 + if (timeoutId) { + clearTimeout(timeoutId); + } abortControllers.delete(requestId); } }