From a1eaae3c04d10a847981350dbbdb821251256062 Mon Sep 17 00:00:00 2001 From: kappa Date: Mon, 19 Jan 2026 09:45:25 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=8B=A4=EB=A5=B8=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EB=AC=B4=EC=9D=91=EB=8B=B5=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getOrCreateUser를 별도 try-catch로 감싸서 DB 오류 시 에러 메시지 전송 - 전체 메시지 처리 로직을 try-catch로 감싸서 모든 오류에 대해 사용자 응답 보장 - 기존: DB 오류 발생 시 webhook handler catch → 500 반환 (사용자 무응답) - 변경: 오류 발생 시에도 "일시적인 오류" 메시지 전송 Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 23 ++++++++++++++++++ src/index.ts | 69 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index f207c38..824d318 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -175,6 +175,7 @@ curl https://telegram-summary-bot.kappa-d8e.workers.dev/webhook-info | Email Worker 파싱 실패 | SMS 형식 변경 | `index.ts`의 정규식 패턴 확인 | | **AI가 도구 호출 안 함** | 키워드 미인식 | 시스템 프롬프트 + 도구 description에 키워드 추가 | | **예치금 최소 금액 제한** | Agent 프롬프트 문제 | Deposit Agent 프롬프트 수정 (OpenAI API) | +| **다른 사용자 응답 없음** | DB 작업 try-catch 누락 | `index.ts:handleMessage` 전체 try-catch 적용 (2026-01 수정) | ### 디버깅 명령어 ```bash @@ -242,6 +243,28 @@ Telegram Webhook → Security Validation → Command/Message Router **AI Fallback:** OpenAI 미설정 시 Workers AI (Llama 3.1 8B) 자동 전환 +### 에러 핸들링 구조 (index.ts:handleMessage) + +``` +Webhook 수신 + ↓ +보안 검증 실패 → 401 반환 (로그 기록) + ↓ +Rate Limit 초과 → 경고 메시지 전송 + return + ↓ +사용자 DB 조회/생성 (try-catch) + ↓ 실패 시 → "일시적인 오류" 메시지 전송 + return + ↓ +메시지 처리 (전체 try-catch) + ├── 명령어 처리 (handleCommand) + └── AI 응답 생성 (generateAIResponse) + ↓ 실패 시 → "메시지 처리 오류" 메시지 전송 + ↓ +응답 전송 (sendMessage) +``` + +**중요:** 모든 DB 작업과 AI 호출은 try-catch로 감싸서 오류 시에도 사용자에게 메시지 전송 + ### 동적 도구 로딩 **목적:** 토큰 절약 + AI 선택 정확도 향상 diff --git a/src/index.ts b/src/index.ts index 89a4c50..b329c96 100644 --- a/src/index.ts +++ b/src/index.ts @@ -62,38 +62,49 @@ async function handleMessage( return; } - // 사용자 처리 - const userId = await getOrCreateUser( - env.DB, - telegramUserId, - message.from.first_name, - message.from.username - ); + // 사용자 처리 (오류 시 사용자에게 알림) + let userId: number; + try { + userId = await getOrCreateUser( + env.DB, + telegramUserId, + message.from.first_name, + message.from.username + ); + } catch (dbError) { + console.error('[handleMessage] 사용자 DB 오류:', dbError); + await sendMessage( + env.BOT_TOKEN, + chatId, + '⚠️ 일시적인 오류가 발생했습니다. 잠시 후 다시 시도해주세요.' + ); + return; + } let responseText: string; - // 명령어 처리 - if (text.startsWith('/')) { - const [command, ...argParts] = text.split(' '); - const args = argParts.join(' '); - responseText = await handleCommand(env, userId, chatIdStr, command, args); + try { + // 명령어 처리 + if (text.startsWith('/')) { + const [command, ...argParts] = text.split(' '); + const args = argParts.join(' '); + responseText = await handleCommand(env, userId, chatIdStr, command, args); - // /start 명령어는 미니앱 버튼과 함께 전송 - if (command === '/start') { - await sendMessageWithKeyboard(env.BOT_TOKEN, chatId, responseText, [ - [{ text: '🌐 서비스 보기', web_app: { url: 'https://hosting.anvil.it.com' } }], - [{ text: '💬 문의하기', url: 'https://t.me/AnvilForgeBot' }], - ]); - return; - } - } else { - // 타이핑 표시 - await sendChatAction(env.BOT_TOKEN, chatId, 'typing'); + // /start 명령어는 미니앱 버튼과 함께 전송 + if (command === '/start') { + await sendMessageWithKeyboard(env.BOT_TOKEN, chatId, responseText, [ + [{ text: '🌐 서비스 보기', web_app: { url: 'https://hosting.anvil.it.com' } }], + [{ text: '💬 문의하기', url: 'https://t.me/AnvilForgeBot' }], + ]); + return; + } + } else { + // 타이핑 표시 + await sendChatAction(env.BOT_TOKEN, chatId, 'typing'); - // 1. 사용자 메시지 버퍼에 추가 - await addToBuffer(env.DB, userId, chatIdStr, 'user', text); + // 1. 사용자 메시지 버퍼에 추가 + await addToBuffer(env.DB, userId, chatIdStr, 'user', text); - try { // 2. AI 응답 생성 responseText = await generateAIResponse(env, userId, chatIdStr, text, telegramUserId); @@ -106,10 +117,10 @@ async function handleMessage( if (summarized) { responseText += '\n\n👤 프로필이 업데이트되었습니다.'; } - } catch (error) { - console.error('AI Response error:', error); - responseText = `⚠️ AI 응답 생성 중 오류가 발생했습니다.\n\n${String(error)}`; } + } catch (error) { + console.error('[handleMessage] 처리 오류:', error); + responseText = '⚠️ 메시지 처리 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.'; } // 버튼 데이터 파싱