mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-09-20 13:40:11 +08:00
fix: fetchWithRetry 对 429 限流增加指数退避与 Retry-After 尊重
- useHttp.calculateRetryDelay:优先读服务端 Retry-After 头;429 用指数退避 (1000*2^attempt, 封顶 30s);其余 5xx 仍固定延迟,避免限流场景频繁重试浪费带宽 - debian/changelog 测试版本号 5.2.1.2-test - 验证:vue-tsc 0 / eslint 0 / dpkg-buildpackage 打包成功 审查项实证(其余 3 项均误报/已有防护,不改): - ① install-manager pkgname 二次校验:已有 PKGNAME_PATTERN(/^[a-zA-Z0-9._+-]+$/) 在 parseAppPayload/addInstallTask/launch-app 三入口校验,且 spawn 全用 shell:false 参数逐元素传递,命令注入不可达;审查建议的 replace 属冗余纵深防御,不改 - ② InstalledAppsModal /var/lib/ 宽泛:误报,真实白名单(400-409行)已是 /var/lib/apm/ 与 /var/lib/dpkg/info/ 具体子目录,无宽泛 /var/lib/ 项 - ③ useAppState.ts 注入模式缺注册检查:误报,useAppState.ts 无 registerRequireLogin; 真实 registerRequireLogin 在 useFavorites/useAppDetail,默认 ()=>true 为刻意安全兜底 (未注册=放行),审查建议的 InjectionPoint 包装会破坏该语义,不改
This commit is contained in:
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
spark-store (5.2.1.1-test) UNRELEASED; urgency=medium
|
||||
spark-store (5.2.1.2-test) UNRELEASED; urgency=medium
|
||||
|
||||
* Initial release. (Closes: #nnnn) <nnnn is the bug number of your ITP>
|
||||
|
||||
|
||||
@@ -23,6 +23,24 @@ axiosInstance.interceptors.request.use(createCacheBusterInterceptor());
|
||||
// 5xx / 网络错误 / 超时重试;4xx(如 404)快速失败
|
||||
const RETRYABLE_STATUS = new Set([502, 503, 504]);
|
||||
|
||||
// 计算重试延迟:优先尊重服务端 Retry-After 头;429 限流用指数退避(封顶 30s);
|
||||
// 其余 5xx 用固定延迟。避免对限流场景频繁重试浪费带宽。
|
||||
const calculateRetryDelay = (
|
||||
status: number | undefined,
|
||||
attempt: number,
|
||||
retryAfterHeader?: string,
|
||||
fixedDelayMs = 500,
|
||||
): number => {
|
||||
if (retryAfterHeader) {
|
||||
const seconds = Number.parseInt(retryAfterHeader, 10);
|
||||
if (!Number.isNaN(seconds) && seconds > 0) return seconds * 1000;
|
||||
}
|
||||
if (status === 429) {
|
||||
return Math.min(1000 * 2 ** attempt, 30000);
|
||||
}
|
||||
return fixedDelayMs;
|
||||
};
|
||||
|
||||
export const fetchWithRetry = async <T>(
|
||||
path: string,
|
||||
signal?: AbortSignal,
|
||||
@@ -46,7 +64,16 @@ export const fetchWithRetry = async <T>(
|
||||
if (!retryable || attempt === retries) {
|
||||
return null;
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, retryDelayMs));
|
||||
const retryAfter = ae.response?.headers?.["retry-after"] as
|
||||
| string
|
||||
| undefined;
|
||||
const delay = calculateRetryDelay(
|
||||
status,
|
||||
attempt,
|
||||
retryAfter,
|
||||
retryDelayMs,
|
||||
);
|
||||
await new Promise((r) => setTimeout(r, delay));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user