Skip to content

추출 부분값 200 을 계약 위반으로 튕기지 않는다 - 원격 응답 경계 게이트 완화 #950

Description

@m-a-king

extractor 가 부분값을 200 으로 내려보내기 시작했는데, core 의 원격 응답 경계가 여전히 세 필드를 모두 요구해 그 200 을 계약 위반으로 튕긴다. INCOMPLETE 분기는 만들어져 있지만 진입로가 닫혀 있다.

RemoteExtractionContract.toSnapshotname, imageUrl, currentPrice 를 각각 non-null 로 검사하고 하나라도 비면 contractViolation 으로 transientFailure(502) 를 던진다. #945 는 도메인 안쪽(ItemSnapshot.markExtracted 의 READY / INCOMPLETE / FAILED 3갈래, 알림 타입, 메트릭, SSE, 응답 DTO)만 열었고 이 경계는 변경 대상에 없었다. 그 시점 extractor 가 부분값을 422 로 닫고 있어 발동하지 않는 코드였기 때문이다(#945 본문에도 그렇게 적혀 있다).

TeamPiKi/extractor#37 이 머지되면서(2026-08-16 02:47 KST) 전제가 뒤집혔다. 이제 extractor 는 값이 하나라도 있으면 200 으로 내려보내고 하나도 못 건졌을 때만 422(UNTRUSTWORTHY_VALUE)로 닫는다. 그 결과 부분값은 markExtracted 에 도달하지 못하고 경계에서 502 로 튕겨 재시도 소진 후 FAILED 로 끝난다.

prod 실측 (2026-08-16 06:15 KST, item 1910, toss.shopping/t/2571175119)

trace 27fc86dd4414d5316628fb41fd726b1e 는 전 구간 HTTP 200 이다. 페이지 fetch 200, Gemini 200, extractor 응답 200. 실패는 core 의 계약 검증 층에서만 났다.

06:15:56.342 [extractor] extraction incomplete missing=currentPrice method=LLM
06:15:56.346 [core]      remote extract contract violation: missing required field
06:15:56.347 [core]      item.parse.retry item=1910 category=RETRYABLE status=502
06:15:56.364 [core]      item.parse.result item=1910 result=failed reason=retry_exhausted
06:15:56.393 [core]      알림 디스패치 type=ITEM_PARSING_FAILED 수신자=1명

사용자에게는 실패 알림이 나갔다. name 과 imageUrl 은 뽑혔는데도 버려졌다.

이미지 경로도 같은 게이트를 공유한다

HttpImageSnapshotExtractor 가 링크와 같은 RemoteExtractionContract.postForSnapshot 을 쓴다. 따라서 #944 의 원래 동인이던 이미지 등록 18건 중 16건 실패(89%)도 아직 해소되지 않았다. 사진에 가격이 박혀 있지 않은 정상 입력이 여전히 502 로 튕긴다.

무엇을

  • RemoteExtractionContract.toSnapshot 의 필수 필드 게이트를 extractor 계약에 맞춘다. 세 필드가 모두 비면 계약 위반, 하나라도 있으면 통과. 나머지 판정(READY / INCOMPLETE / FAILED)은 ItemSnapshot.markExtracted 가 이미 쥐고 있으므로 경계는 판정하지 않는다.
  • 그 위 주석 블록("extractor 는 2xx 로 name / imageUrl / currentPrice 를 non-null 로 보장한다")을 새 계약으로 갱신한다. 지금 주석은 뒤집힌 전제를 설명하고 있어 다음 사람을 오도한다.
  • 링크와 이미지가 같은 계약을 공유하므로 한 곳 수정으로 둘 다 열린다. 양 경로 통합 테스트로 부분값 200 이 INCOMPLETE 로 귀결되는지 검증한다.
  • 하나도 못 건진 응답이 422 로 닫히는 기존 경로는 그대로 둔다.

참고

Metadata

Metadata

Assignees

Labels

fix외부 가시적 결함 수정

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions