Skip to content

feat: 피드백 생성 실패 신호 — FAILED 콜백으로 무기한 대기 제거 - #206

Merged
Jaeho-Site merged 3 commits into
devfrom
feat/feedback-failed-callback
Aug 22, 2026
Merged

feat: 피드백 생성 실패 신호 — FAILED 콜백으로 무기한 대기 제거#206
Jaeho-Site merged 3 commits into
devfrom
feat/feedback-failed-callback

Conversation

@Jaeho-Site

Copy link
Copy Markdown
Contributor

변경 사항

문제

feedback_consumer 는 top-level 예외 보호가 없어 예상 못 한 예외(트랜스크립트/RAG 컨텍스트 빌드, payload 조립 등) 발생 시 reject → dlq.ai.generate.feedback 로만 격리되고 콜백이 발행되지 않았다. Core 는 아무 신호도 받지 못해 세션이 "피드백 생성 중" 상태로 무기한 남는다. questions/followup/repository consumer 에는 이미 적용된 실패 신호 패턴에서 feedback 경로만 빠져 있던 gap.

AI (ai/)

  • handle() 본문을 payload 를 반환하는 _process() 로 추출, 생성 전 구간을 try/except 로 보호
  • 실패 시 FeedbackCallbackPayload(status=FAILED) 발행 후 ack — TypeError(LLM 출력 스키마 불일치)는 GENERATION_SCHEMA_INVALID/retriable=false, 그 외 UNEXPECTED/retriable=true (형제 consumer 와 동일 분류)
  • 성공 콜백 발행 실패는 생성 실패가 아니다 — FAILED 오인 발행 없이 원 예외로 DLQ (기존 재처리성 유지)
  • 콜백을 하나도 못 낸 채 DLQ 로 가는 경로는 LruIdempotencyStore.unmark 로 멱등 마킹을 되돌려 재주입 시 duplicate skip 으로 삼켜지지 않게 함
  • statusGenerationStatus Literal 재사용(기본 OK — 구버전 하위호환), errorMessage 500자 상한

Core (backend/)

  • FeedbackCallbackPayload 에 status/errorCode/errorMessage/retriable 추가 (구버전 13-arg 생성자는 status=OK 위임)
  • FeedbackCallbackService.apply 가 저장 전 isFailed() 분기 — 저장 없이 SSE ERROR(SessionErrorNotice, scope=FEEDBACK) 를 세션/유저 채널에 발행. AI errorMessage 원문은 서버 로그에만 남기고 클라이언트에는 화이트리스트 문구만 전송 (QuestionsCallbackService 와 동일 원칙)

문서

  • docs/messaging.md §5.11 실패 케이스·§6 정책 행, docs/event-stream.md §3.6 SessionErrorNotice 스키마
  • ai/CLAUDE.md·backend/CLAUDE.md 구현 기록 (+ backend POOL 실패 서술의 stale 정정)
  • infra/ 변경 없음 — core.callback.feedback 큐·DLQ 는 definitions.json 에 기존재

검증

  • ai: pytest 374 passed (+4: FAILED 콜백 경로 2, 스키마 분류 1, 성공발행실패 DLQ 유지 1), -k feedback 스모크 55 passed, black clean
  • backend: FeedbackCallbackServiceTest +2 (FAILED → 저장 없이 ERROR 2채널·내부 메시지 미노출, status null → OK 저장 회귀). 전체 233 passed — 로컬 실패 4건은 Docker(Testcontainers) 부재 환경 실패로 baseline 과 동일, 신규 실패 0
  • 코드 리뷰에서 지적된 정확성 이슈 3건(성공 발행 실패의 FAILED 오인, retriable 무조건 true, 멱등 마킹의 DLQ 재주입 무력화) 반영 완료

후속 (별도 작업으로 기록)

  • 프론트 피드백 대기 화면의 SSE ERROR(scope=FEEDBACK) 소비 (현재는 폴링 타임아웃으로 종료)
  • 피드백 실패의 영속 마커 (SSE 미접속 클라이언트 대비)
  • consumer 실패 신호 래퍼 일원화 (questions/followup 의 잔여 무방비 구간 포함)

feedback_consumer 의 예상 못 한 예외가 DLQ 로만 격리돼 콜백 없이 세션이
'피드백 생성 중'에 무기한 멈추던 gap 수정. handle 본문을 _process 로 추출해
생성 구간 실패 시 status=FAILED 콜백(TypeError→GENERATION_SCHEMA_INVALID/
retriable=false, 그 외 UNEXPECTED/retriable=true) 발행 후 ack. 성공 콜백 발행
실패는 FAILED 오인 없이 원 예외로 DLQ 유지, 콜백 0건 DLQ 경로는 멱등 unmark 로
재주입 재처리 보장. errorMessage 500자 상한, GenerationStatus Literal 재사용.
FeedbackCallbackPayload 에 status/errorCode/errorMessage/retriable 추가
(구버전 13-arg 생성자는 status=OK 위임). FeedbackCallbackService.apply 가
저장 전 isFailed() 분기 — 저장 없이 SseEventType.ERROR(SessionErrorNotice,
scope=FEEDBACK)를 세션/유저 채널에 발행하고 멱등 마킹. AI errorMessage 원문은
서버 로그에만 남기고 클라이언트에는 화이트리스트 문구만 전송.
messaging.md §5.11 실패 케이스 블록·§6 정책 행 추가, AI 서버 절에
feedback_consumer 실패 신호 기록. event-stream.md §3.6 에 SessionErrorNotice
형태(scope=FOLLOWUP|FEEDBACK)와 사용자 문구 원칙 문서화.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant