fix: 다른 사용자 무응답 버그 수정
- getOrCreateUser를 별도 try-catch로 감싸서 DB 오류 시 에러 메시지 전송 - 전체 메시지 처리 로직을 try-catch로 감싸서 모든 오류에 대해 사용자 응답 보장 - 기존: DB 오류 발생 시 webhook handler catch → 500 반환 (사용자 무응답) - 변경: 오류 발생 시에도 "일시적인 오류" 메시지 전송 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
23
CLAUDE.md
23
CLAUDE.md
@@ -175,6 +175,7 @@ curl https://telegram-summary-bot.kappa-d8e.workers.dev/webhook-info
|
|||||||
| Email Worker 파싱 실패 | SMS 형식 변경 | `index.ts`의 정규식 패턴 확인 |
|
| Email Worker 파싱 실패 | SMS 형식 변경 | `index.ts`의 정규식 패턴 확인 |
|
||||||
| **AI가 도구 호출 안 함** | 키워드 미인식 | 시스템 프롬프트 + 도구 description에 키워드 추가 |
|
| **AI가 도구 호출 안 함** | 키워드 미인식 | 시스템 프롬프트 + 도구 description에 키워드 추가 |
|
||||||
| **예치금 최소 금액 제한** | Agent 프롬프트 문제 | Deposit Agent 프롬프트 수정 (OpenAI API) |
|
| **예치금 최소 금액 제한** | Agent 프롬프트 문제 | Deposit Agent 프롬프트 수정 (OpenAI API) |
|
||||||
|
| **다른 사용자 응답 없음** | DB 작업 try-catch 누락 | `index.ts:handleMessage` 전체 try-catch 적용 (2026-01 수정) |
|
||||||
|
|
||||||
### 디버깅 명령어
|
### 디버깅 명령어
|
||||||
```bash
|
```bash
|
||||||
@@ -242,6 +243,28 @@ Telegram Webhook → Security Validation → Command/Message Router
|
|||||||
|
|
||||||
**AI Fallback:** OpenAI 미설정 시 Workers AI (Llama 3.1 8B) 자동 전환
|
**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 선택 정확도 향상
|
**목적:** 토큰 절약 + AI 선택 정확도 향상
|
||||||
|
|||||||
69
src/index.ts
69
src/index.ts
@@ -62,38 +62,49 @@ async function handleMessage(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 사용자 처리
|
// 사용자 처리 (오류 시 사용자에게 알림)
|
||||||
const userId = await getOrCreateUser(
|
let userId: number;
|
||||||
env.DB,
|
try {
|
||||||
telegramUserId,
|
userId = await getOrCreateUser(
|
||||||
message.from.first_name,
|
env.DB,
|
||||||
message.from.username
|
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;
|
let responseText: string;
|
||||||
|
|
||||||
// 명령어 처리
|
try {
|
||||||
if (text.startsWith('/')) {
|
// 명령어 처리
|
||||||
const [command, ...argParts] = text.split(' ');
|
if (text.startsWith('/')) {
|
||||||
const args = argParts.join(' ');
|
const [command, ...argParts] = text.split(' ');
|
||||||
responseText = await handleCommand(env, userId, chatIdStr, command, args);
|
const args = argParts.join(' ');
|
||||||
|
responseText = await handleCommand(env, userId, chatIdStr, command, args);
|
||||||
|
|
||||||
// /start 명령어는 미니앱 버튼과 함께 전송
|
// /start 명령어는 미니앱 버튼과 함께 전송
|
||||||
if (command === '/start') {
|
if (command === '/start') {
|
||||||
await sendMessageWithKeyboard(env.BOT_TOKEN, chatId, responseText, [
|
await sendMessageWithKeyboard(env.BOT_TOKEN, chatId, responseText, [
|
||||||
[{ text: '🌐 서비스 보기', web_app: { url: 'https://hosting.anvil.it.com' } }],
|
[{ text: '🌐 서비스 보기', web_app: { url: 'https://hosting.anvil.it.com' } }],
|
||||||
[{ text: '💬 문의하기', url: 'https://t.me/AnvilForgeBot' }],
|
[{ text: '💬 문의하기', url: 'https://t.me/AnvilForgeBot' }],
|
||||||
]);
|
]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 타이핑 표시
|
// 타이핑 표시
|
||||||
await sendChatAction(env.BOT_TOKEN, chatId, 'typing');
|
await sendChatAction(env.BOT_TOKEN, chatId, 'typing');
|
||||||
|
|
||||||
// 1. 사용자 메시지 버퍼에 추가
|
// 1. 사용자 메시지 버퍼에 추가
|
||||||
await addToBuffer(env.DB, userId, chatIdStr, 'user', text);
|
await addToBuffer(env.DB, userId, chatIdStr, 'user', text);
|
||||||
|
|
||||||
try {
|
|
||||||
// 2. AI 응답 생성
|
// 2. AI 응답 생성
|
||||||
responseText = await generateAIResponse(env, userId, chatIdStr, text, telegramUserId);
|
responseText = await generateAIResponse(env, userId, chatIdStr, text, telegramUserId);
|
||||||
|
|
||||||
@@ -106,10 +117,10 @@ async function handleMessage(
|
|||||||
if (summarized) {
|
if (summarized) {
|
||||||
responseText += '\n\n<i>👤 프로필이 업데이트되었습니다.</i>';
|
responseText += '\n\n<i>👤 프로필이 업데이트되었습니다.</i>';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('AI Response error:', error);
|
|
||||||
responseText = `⚠️ AI 응답 생성 중 오류가 발생했습니다.\n\n<code>${String(error)}</code>`;
|
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[handleMessage] 처리 오류:', error);
|
||||||
|
responseText = '⚠️ 메시지 처리 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 버튼 데이터 파싱
|
// 버튼 데이터 파싱
|
||||||
|
|||||||
Reference in New Issue
Block a user