From 47f82586d26f95425e519cf60b2b5037c6cfcf7f Mon Sep 17 00:00:00 2001 From: posimai Date: Tue, 14 Apr 2026 23:39:46 +0900 Subject: [PATCH] fix(brain): retry 503 once, don't persist failure message to DB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - analyzeWithGemini: 503(一時高負荷)は4秒後に1回リトライ - 失敗時は null を返し、呼び出し側で DB を更新しない → 「AI分析に失敗しました」がsummaryとして永続化されなくなる Co-Authored-By: Claude Sonnet 4.6 --- server.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/server.js b/server.js index 8d34c473..0b6b4bbc 100644 --- a/server.js +++ b/server.js @@ -428,8 +428,8 @@ function smartExtract(text, maxLen) { return front + '\n\n[...中略...]\n\n' + back; } -async function analyzeWithGemini(title, fullText, url) { - if (!genAI) return { summary: (fullText || '').slice(0, 120) || '(要約なし)', topics: ['その他'], readingTime: 3 }; +async function analyzeWithGemini(title, fullText, url, _retry = false) { + if (!genAI) return null; try { const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash', @@ -471,11 +471,13 @@ ${smartExtract(fullText || '', 5000)} if (typeof result !== 'undefined' && result?.response) { console.error('[Gemini] Raw response:', result.response.text()); } - return { - summary: 'AI分析に失敗しました。しばらく後にお試しください。', - topics: ['その他'], - readingTime: 3 - }; + // 503(一時的高負荷)は1回だけリトライ + if (!_retry && e.status === 503) { + console.warn('[Gemini] 503 detected, retrying in 4s...'); + await new Promise(r => setTimeout(r, 4000)); + return analyzeWithGemini(title, fullText, url, true); + } + return null; } } @@ -1463,6 +1465,7 @@ function buildRouter() { if (checkRateLimit('gemini_analyze', savedUserId, 50, 60 * 60 * 1000)) { analyzeWithGemini(finalTitle, fullText || meta.desc, url).then(async (ai) => { + if (!ai) { console.warn(`[Brain API] AI analysis skipped (null) for ${url}`); return; } await pool.query(` UPDATE articles SET summary=$1, topics=$2, reading_time=$3 WHERE user_id=$4 AND url=$5 @@ -1563,6 +1566,7 @@ function buildRouter() { if (checkRateLimit('gemini_analyze', savedUserId, 50, 60 * 60 * 1000)) { analyzeWithGemini(meta.title, fullText, url).then(async (ai) => { + if (!ai) { console.warn(`[Brain API] AI analysis skipped (null) for ${url}`); return; } await pool.query(` UPDATE articles SET summary=$1, topics=$2, reading_time=$3 WHERE user_id=$4 AND url=$5