feat: 增强 GPC 结账流程的错误处理与重试机制,优化超时管理

This commit is contained in:
QLHazyCoder
2026-05-10 01:31:42 +08:00
parent 712a6ddfba
commit 35bf6a2c32
7 changed files with 214 additions and 31 deletions
+26 -3
View File
@@ -257,11 +257,34 @@
throw new Error('当前运行环境不支持 fetch,无法调用 GPC API。');
}
const controller = typeof AbortController === 'function' ? new AbortController() : null;
const timer = controller ? setTimeout(() => controller.abort(), Math.max(1000, Number(timeoutMs) || 30000)) : null;
const effectiveTimeoutMs = Math.max(1000, Number(timeoutMs) || 30000);
let didTimeout = false;
let timer = null;
const buildTimeoutError = () => new Error(`GPC API 请求超时(>${Math.round(effectiveTimeoutMs / 1000)} 秒):${url}`);
const timeoutPromise = new Promise((_, reject) => {
timer = setTimeout(() => {
didTimeout = true;
reject(buildTimeoutError());
if (controller) {
controller.abort();
}
}, effectiveTimeoutMs);
});
try {
const response = await fetcher(url, { ...options, ...(controller ? { signal: controller.signal } : {}) });
const data = await response.json().catch(() => ({}));
const response = await Promise.race([
fetcher(url, { ...options, ...(controller ? { signal: controller.signal } : {}) }),
timeoutPromise,
]);
const data = await Promise.race([
response.json().catch(() => ({})),
timeoutPromise,
]);
return { response, data };
} catch (error) {
if (didTimeout || error?.name === 'AbortError') {
throw buildTimeoutError();
}
throw error;
} finally {
if (timer) clearTimeout(timer);
}
+26 -3
View File
@@ -209,11 +209,34 @@
throw new Error('当前运行环境不支持 fetch,无法调用 GPC API。');
}
const controller = typeof AbortController === 'function' ? new AbortController() : null;
const timer = controller ? setTimeout(() => controller.abort(), Math.max(1000, Number(timeoutMs) || 30000)) : null;
const effectiveTimeoutMs = Math.max(1000, Number(timeoutMs) || 30000);
let didTimeout = false;
let timer = null;
const buildTimeoutError = () => new Error(`GPC API 请求超时(>${Math.round(effectiveTimeoutMs / 1000)} 秒):${url}`);
const timeoutPromise = new Promise((_, reject) => {
timer = setTimeout(() => {
didTimeout = true;
reject(buildTimeoutError());
if (controller) {
controller.abort();
}
}, effectiveTimeoutMs);
});
try {
const response = await fetcher(url, { ...options, ...(controller ? { signal: controller.signal } : {}) });
const data = await response.json().catch(() => ({}));
const response = await Promise.race([
fetcher(url, { ...options, ...(controller ? { signal: controller.signal } : {}) }),
timeoutPromise,
]);
const data = await Promise.race([
response.json().catch(() => ({})),
timeoutPromise,
]);
return { response, data };
} catch (error) {
if (didTimeout || error?.name === 'AbortError') {
throw buildTimeoutError();
}
throw error;
} finally {
if (timer) clearTimeout(timer);
}