From c778e4c85dfd93b84196c6d473cb8707afdab347 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Sat, 4 Jul 2026 00:03:12 +0000 Subject: [PATCH] =?UTF-8?q?fix(report-ui):=20=D1=80=D0=B5=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=B9=20docx-preflight=20=D0=BF=D1=80=D0=BE=D1=82=D0=B8?= =?UTF-8?q?=D0=B2=20502-=D0=B3=D0=BE=D0=BD=D0=BA=D0=B8=20=D1=81=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D1=83=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20ready=20(?= =?UTF-8?q?#2353)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useFullReport.ts | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/frontend/src/hooks/useFullReport.ts b/frontend/src/hooks/useFullReport.ts index 6482c46e..ace91bb1 100644 --- a/frontend/src/hooks/useFullReport.ts +++ b/frontend/src/hooks/useFullReport.ts @@ -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 { if (format === "pdf") { triggerAnchorDownload(cad, "pdf"); return; } try { - const res = await fetch(downloadUrl(cad, "docx"), { method: "HEAD" }); - // Любой не-OK (404 легаси-рана, 5xx) — не даём молча скачать страницу ошибки. + 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 и после ретрая) — не даём молча скачать + // страницу ошибки, но и НЕ просим пересобрать (файл скорее всего цел). + onError("Не удалось скачать отчёт — повторите через минуту"); return; } } catch { @@ -160,10 +173,8 @@ export function useFullReport(cad: string): UseFullReportResult { const pendingFormatRef = useRef("pdf"); // Стабильный колбэк ошибки docx-download'а для triggerReportDownload. - const handleDownloadError = useCallback(() => { - setDownloadError( - "Пересоберите отчёт — DOCX для старого прогона отсутствует", - ); + const handleDownloadError = useCallback((message: string) => { + setDownloadError(message); }, []); // ── POST enqueue ────────────────────────────────────────────────────────────