9ad2152816
新增图片编辑器请求重试配置 生成请求遇到429等临时错误自动重试 上传凭证、资产确认和直传上传共用重试策略 补充图片编辑器重试参数和直传429测试
77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
import type { ApiRetryOptions } from '../apiClient';
|
|
|
|
const EDITOR_RETRYABLE_STATUS_CODES = [408, 425, 429, 502, 503, 504];
|
|
const EDITOR_RETRY_MAX_RETRIES = 2;
|
|
const EDITOR_RETRY_BASE_DELAY_MS = 800;
|
|
const EDITOR_RETRY_MAX_DELAY_MS = 3000;
|
|
|
|
export const EDITOR_REQUEST_RETRY_OPTIONS = {
|
|
maxRetries: EDITOR_RETRY_MAX_RETRIES,
|
|
baseDelayMs: EDITOR_RETRY_BASE_DELAY_MS,
|
|
maxDelayMs: EDITOR_RETRY_MAX_DELAY_MS,
|
|
retryUnsafeMethods: true,
|
|
retryableStatusCodes: EDITOR_RETRYABLE_STATUS_CODES,
|
|
} satisfies ApiRetryOptions;
|
|
|
|
type EditorDirectUploadTarget = {
|
|
host: string;
|
|
formFields: Record<string, string | null | undefined>;
|
|
};
|
|
|
|
function buildRetryDelayMs(attempt: number) {
|
|
return Math.min(
|
|
EDITOR_RETRY_MAX_DELAY_MS,
|
|
EDITOR_RETRY_BASE_DELAY_MS * Math.max(1, attempt),
|
|
);
|
|
}
|
|
|
|
function waitForRetryDelay(attempt: number) {
|
|
return new Promise((resolve) => {
|
|
setTimeout(resolve, buildRetryDelayMs(attempt));
|
|
});
|
|
}
|
|
|
|
function isRetryableEditorUploadStatus(status: number) {
|
|
return EDITOR_RETRYABLE_STATUS_CODES.includes(status);
|
|
}
|
|
|
|
function buildDirectUploadFormData(
|
|
upload: EditorDirectUploadTarget,
|
|
file: File,
|
|
) {
|
|
const formData = new FormData();
|
|
Object.entries(upload.formFields).forEach(([key, value]) => {
|
|
if (value !== null && value !== undefined) {
|
|
formData.append(key, value);
|
|
}
|
|
});
|
|
formData.append('file', file, file.name);
|
|
return formData;
|
|
}
|
|
|
|
export async function postEditorDirectUploadFile(
|
|
upload: EditorDirectUploadTarget,
|
|
file: File,
|
|
errorMessage: string,
|
|
) {
|
|
for (let attempt = 0; ; attempt += 1) {
|
|
const response = await fetch(upload.host, {
|
|
method: 'POST',
|
|
body: buildDirectUploadFormData(upload, file),
|
|
});
|
|
|
|
if (response.ok) {
|
|
return;
|
|
}
|
|
|
|
if (
|
|
attempt >= EDITOR_RETRY_MAX_RETRIES ||
|
|
!isRetryableEditorUploadStatus(response.status)
|
|
) {
|
|
throw new Error(errorMessage);
|
|
}
|
|
|
|
await waitForRetryDelay(attempt + 1);
|
|
}
|
|
}
|