fix(report-ui): ретрай docx-preflight против 502-гонки сразу после ready
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 59s
CI / openapi-codegen-check (pull_request) Successful in 1m59s
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 59s
CI / openapi-codegen-check (pull_request) Successful in 1m59s
Стресс-свип 2026-07-04 (7 участков): первый HEAD download сразу после status=ready может словить транзиентный 502 (proxy-гонка на моменте записи файла), ретрей через ~30с — чистый 200. Прежний preflight по !res.ok показывал на это «Пересоберите отчёт» — вводит в заблуждение, файл цел. Теперь: 5xx → один ретрай через 1.5с; устойчивый не-OK → честное «Не удалось скачать — повторите через минуту»; 404 (легаси-ран без docx) — прежняя просьба пересобрать. onError теперь несёт message.
This commit is contained in:
parent
36fe33750f
commit
786739f0a6
1 changed files with 19 additions and 8 deletions
|
|
@ -122,17 +122,30 @@ function triggerAnchorDownload(cad: string, format: ReportFormat): void {
|
|||
async function triggerReportDownload(
|
||||
cad: string,
|
||||
format: ReportFormat,
|
||||
onError: () => void,
|
||||
onError: (message: string) => void,
|
||||
): Promise<void> {
|
||||
if (format === "pdf") {
|
||||
triggerAnchorDownload(cad, "pdf");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await fetch(downloadUrl(cad, "docx"), { method: "HEAD" });
|
||||
// Любой не-OK (404 легаси-рана, 5xx) — не даём <a> молча скачать страницу ошибки.
|
||||
let res = await fetch(downloadUrl(cad, "docx"), { method: "HEAD" });
|
||||
// 5xx сразу после status=ready — транзиентная proxy-гонка (стресс-свип
|
||||
// 2026-07-04: первый HEAD после ready ловил 502, ретрей через ~1.5с — 200).
|
||||
// Один ретрай, прежде чем показывать пользователю ошибку.
|
||||
if (!res.ok && res.status !== 404) {
|
||||
await new Promise((r) => setTimeout(r, 1500));
|
||||
res = await fetch(downloadUrl(cad, "docx"), { method: "HEAD" });
|
||||
}
|
||||
if (res.status === 404) {
|
||||
// Легаси-ран без docx_path — честная просьба пересобрать.
|
||||
onError("Пересоберите отчёт — DOCX для старого прогона отсутствует");
|
||||
return;
|
||||
}
|
||||
if (!res.ok) {
|
||||
onError();
|
||||
// Устойчивый не-OK (5xx и после ретрая) — не даём <a> молча скачать
|
||||
// страницу ошибки, но и НЕ просим пересобрать (файл скорее всего цел).
|
||||
onError("Не удалось скачать отчёт — повторите через минуту");
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
|
|
@ -160,10 +173,8 @@ export function useFullReport(cad: string): UseFullReportResult {
|
|||
const pendingFormatRef = useRef<ReportFormat>("pdf");
|
||||
|
||||
// Стабильный колбэк ошибки docx-download'а для triggerReportDownload.
|
||||
const handleDownloadError = useCallback(() => {
|
||||
setDownloadError(
|
||||
"Пересоберите отчёт — DOCX для старого прогона отсутствует",
|
||||
);
|
||||
const handleDownloadError = useCallback((message: string) => {
|
||||
setDownloadError(message);
|
||||
}, []);
|
||||
|
||||
// ── POST enqueue ────────────────────────────────────────────────────────────
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue