From f46dc788cc91ae77c039786be17d9bb0871db41f Mon Sep 17 00:00:00 2001 From: sangwook yoo Date: Thu, 11 Jun 2026 10:28:06 +0900 Subject: [PATCH] =?UTF-8?q?fix(pdf-import):=20=EB=B6=84=EC=84=9D=20?= =?UTF-8?q?=ED=83=80=EC=9E=84=EC=95=84=EC=9B=83=20120s=E2=86=92300s=20?= =?UTF-8?q?=ED=99=95=EB=8C=80=20=E2=80=94=20=EC=84=9C=EB=B2=84=20=EC=A0=95?= =?UTF-8?q?=EC=83=81=20=EC=99=84=EB=A3=8C=20=EC=A7=81=EC=A0=84=20=ED=81=B4?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EC=96=B8=ED=8A=B8=20abort=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : - 서버가 120,011ms 에 200 으로 정상 완료했는데 클라이언트 AbortController 가 정확히 120,000ms 에 fetch 를 끊어 타임아웃 toast 가 뜨던 문제 — gemini-3.1-pro-preview(thinking 비활성 불가) + MEDIA_RESOLUTION_HIGH PDF 분석은 정상 응답도 2분을 넘길 수 있어 300초로 확대 - 추후 진단용으로 서버에 단계별 소요시간(fileReady/generate) debug 로그 추가 Co-Authored-By: Claude Fable 5 --- src/app/api/gemini/floor-plan/route.js | 4 ++++ .../floor-plan/modal/placementShape/PlacementShapeSetting.jsx | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/api/gemini/floor-plan/route.js b/src/app/api/gemini/floor-plan/route.js index a8a8b407..c8e09ca4 100644 --- a/src/app/api/gemini/floor-plan/route.js +++ b/src/app/api/gemini/floor-plan/route.js @@ -195,6 +195,7 @@ export async function POST(req) { const buffer = Buffer.from(await file.arrayBuffer()) + const uploadStarted = Date.now() const uploadResult = await fileManager.uploadFile(buffer, { mimeType: 'application/pdf', displayName: file.name || 'floor-plan.pdf', @@ -202,6 +203,7 @@ export async function POST(req) { uploadedFileName = uploadResult.file.name await waitForFileActive(fileManager, uploadedFileName) + const fileReadyMs = Date.now() - uploadStarted const genAI = new GoogleGenerativeAI(apiKey) const model = genAI.getGenerativeModel({ @@ -217,6 +219,7 @@ export async function POST(req) { const prompt = buildPrompt({ pageMode, facadePages, floorPages }) + const generateStarted = Date.now() const result = await model.generateContent([ { fileData: { @@ -228,6 +231,7 @@ export async function POST(req) { ]) const raw = result.response.text() + logger.debug('[gemini/floor-plan] timing(ms)', { fileReady: fileReadyMs, generate: Date.now() - generateStarted }) logger.debug('[gemini/floor-plan] raw response', raw) logger.debug('[gemini/floor-plan] usageMetadata', result.response.usageMetadata) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index a7d8fd4b..494cbcee 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -40,7 +40,9 @@ const PDF_MAX_FILE_BYTES = 20 * 1024 * 1024 // 분석 요청 타임아웃(ms). 서버 라우트는 파일 처리(최대 60s)+generateContent 로 길어질 수 있어 // 클라이언트에서 backstop 을 둔다. 이 시간을 넘기면 abort 하여 스피너가 영구 멈추지 않도록 한다. -const PDF_ANALYZE_TIMEOUT_MS = 120 * 1000 +// gemini-3.1-pro-preview 는 thinking 비활성화가 불가능 + MEDIA_RESOLUTION_HIGH PDF 분석이라 +// 정상 응답도 2분을 넘길 수 있다(실측 120s). 서버 완료 직전에 클라이언트가 끊지 않도록 여유를 둔다. +const PDF_ANALYZE_TIMEOUT_MS = 300 * 1000 const PDF_PAGE_MODE = { ALL: 'all',