fix: 修正自定义镜像优先级并发布 v2.1.6
构建与发布 / 单测与集成测试 (push) Has been cancelled
构建与发布 / 发布 GitHub Release (push) Has been cancelled
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (arm64, linux, ubuntu-24.04-arm) (push) Has been cancelled
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (arm64, macos, macos-15) (push) Has been cancelled
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (x64, linux, ubuntu-24.04) (push) Has been cancelled
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (x64, windows, windows-2025) (push) Has been cancelled
构建与发布 / 单测与集成测试 (push) Has been cancelled
构建与发布 / 发布 GitHub Release (push) Has been cancelled
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (arm64, linux, ubuntu-24.04-arm) (push) Has been cancelled
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (arm64, macos, macos-15) (push) Has been cancelled
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (x64, linux, ubuntu-24.04) (push) Has been cancelled
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (x64, windows, windows-2025) (push) Has been cancelled
用户配置自定义 Z-Library 镜像后,旧会话记录的内置镜像仍被排在前面, 与界面“自定义优先”的约定不一致。调整请求顺序,让自定义镜像严格优先; 全部镜像失败时保留首个自定义镜像的错误,避免被后续兜底错误覆盖。 版本更新到 2.1.6,并补充优先级与错误归因回归测试。
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "peoplelib",
|
||||
"version": "2.1.5",
|
||||
"version": "2.1.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "peoplelib",
|
||||
"version": "2.1.5",
|
||||
"version": "2.1.6",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"foliate-js": "1.0.1",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "peoplelib",
|
||||
"version": "2.1.5",
|
||||
"version": "2.1.6",
|
||||
"description": "多源开放文献、电子书与本地书库客户端",
|
||||
"main": "main.js",
|
||||
"author": "peoplelib",
|
||||
|
||||
@@ -624,6 +624,53 @@ test('zlib: 移除当前会话的非内置镜像会清除旧会话', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('zlib: 自定义镜像优先于旧会话记录的内置镜像', async () => {
|
||||
const zlib = h.freshRequire('sources/zlib.js');
|
||||
const auth = require('../sources/zlib-auth');
|
||||
const orig = {
|
||||
getCustomMirrors: auth.getCustomMirrors,
|
||||
getSession: auth.getSession,
|
||||
setSession: auth.setSession
|
||||
};
|
||||
auth.getCustomMirrors = () => ['https://custom.example'];
|
||||
auth.getSession = () => ({ userId: '1', userKey: 'k', mirror: 'https://1lib.sk' });
|
||||
auth.setSession = () => {};
|
||||
try {
|
||||
h.resetCalls();
|
||||
h.setHandler((url) => {
|
||||
assert.ok(url.startsWith('https://custom.example/'), `先请求了旧会话镜像:${url}`);
|
||||
return h.makeResponse({ body: { success: 1, books: [] } });
|
||||
});
|
||||
await zlib.list(1);
|
||||
assert.strictEqual(h.getCalls().length, 1, '自定义镜像成功后仍请求了内置镜像');
|
||||
} finally {
|
||||
Object.assign(auth, orig);
|
||||
}
|
||||
});
|
||||
|
||||
test('zlib: 全部失败时保留自定义镜像的首要错误', async () => {
|
||||
const zlib = h.freshRequire('sources/zlib.js');
|
||||
const auth = require('../sources/zlib-auth');
|
||||
const orig = {
|
||||
getCustomMirrors: auth.getCustomMirrors,
|
||||
getSession: auth.getSession
|
||||
};
|
||||
auth.getCustomMirrors = () => ['https://custom.example'];
|
||||
auth.getSession = () => ({ userId: '1', userKey: 'k', mirror: 'https://1lib.sk' });
|
||||
try {
|
||||
h.setHandler((url) => {
|
||||
if (url.startsWith('https://custom.example/')) throw new Error('请求超时,站点无响应');
|
||||
throw new Error('该镜像返回了非预期内容');
|
||||
});
|
||||
await assert.rejects(
|
||||
zlib.list(1),
|
||||
/自定义镜像失败:请求超时,站点无响应;其余 \d+ 个镜像也未成功/
|
||||
);
|
||||
} finally {
|
||||
Object.assign(auth, orig);
|
||||
}
|
||||
});
|
||||
|
||||
// 实测:会话过期时 /file 返回 400 + {"success":0,"error":"Please login"}。
|
||||
// 若按 HTTP 状态码短路,真实原因会被吞掉,自动重登也不会触发。
|
||||
test('zlib: 4xx+JSON 的会话过期能被识别并自动重新登录', async () => {
|
||||
|
||||
+17
-4
@@ -215,12 +215,17 @@ async function callOn(mirror, path, params, session, method) {
|
||||
}
|
||||
|
||||
async function attempt(session, path, params, method) {
|
||||
const custom = auth.getCustomMirrors();
|
||||
const mirrors = getMirrors();
|
||||
const ordered = session.mirror
|
||||
// 用户显式配置镜像后必须严格优先于旧会话镜像,否则界面写着“自定义优先”,
|
||||
// 实际却仍先等待上次成功但现在已失效的默认域名。
|
||||
const ordered = custom.length
|
||||
? mirrors
|
||||
: session.mirror
|
||||
? [session.mirror, ...mirrors.filter((m) => m !== session.mirror)]
|
||||
: mirrors;
|
||||
|
||||
let lastErr;
|
||||
const errors = [];
|
||||
for (const m of ordered) {
|
||||
try {
|
||||
const j = await callOn(m, path, params, session, method);
|
||||
@@ -228,10 +233,18 @@ async function attempt(session, path, params, method) {
|
||||
return { ok: true, data: j };
|
||||
} catch (e) {
|
||||
if (e.code === 'AUTH_STALE') return { ok: false, stale: true, error: e };
|
||||
lastErr = e;
|
||||
errors.push(e);
|
||||
}
|
||||
}
|
||||
return { ok: false, stale: false, error: lastErr };
|
||||
if (errors.length <= 1) {
|
||||
return { ok: false, stale: false, error: errors[0] };
|
||||
}
|
||||
const first = errors[0];
|
||||
const label = custom.length ? '自定义镜像失败' : '首选镜像失败';
|
||||
const summary = new Error(
|
||||
`${label}:${(first && first.message) || String(first)};其余 ${errors.length - 1} 个镜像也未成功`
|
||||
);
|
||||
return { ok: false, stale: false, error: summary };
|
||||
}
|
||||
|
||||
async function apiCall(path, params = {}, method = 'GET') {
|
||||
|
||||
Reference in New Issue
Block a user