Skip to content

fix : API 봉투를 안 벗겨 네 화면이 비어 있던 문제 수정 - #34

Merged
dldnsgkr merged 3 commits into
mainfrom
fix/domain-status-polling
Aug 19, 2026
Merged

fix : API 봉투를 안 벗겨 네 화면이 비어 있던 문제 수정#34
dldnsgkr merged 3 commits into
mainfrom
fix/domain-status-polling

Conversation

@dldnsgkr

Copy link
Copy Markdown
Contributor

서버는 200을 주는데 FE가 응답을 통째로 버리고 있던 자리를 고칩니다. 도메인·배포·인프라·환경변수 네 화면이 현재 운영에서 비어 있습니다.

원인

succesResponse는 axios 바디, 즉 API 봉투 {status, code, message, data}를 그대로 돌려줍니다(응답 인터셉터도 벗기지 않습니다). 그런데 네 개 API 파일이 그 봉투를 알맹이 스키마에 그대로 넘기고 있었습니다.

// src/api/projects.ts — 정상
const body = succesResponse<ApiResponse<GetProjectListResType>>(response);
return getProjectListResSchema.parse(body.data);          // .data 를 벗긴다

// src/api/domains.ts — 봉투째 넘김
const data = succesResponse<GetProjectDomainListResType>(response);
return getProjectDomainListResSchema.parse(data);         // 배열 스키마에 봉투가 들어간다

배열을 기대하는 스키마에 객체가 들어가 zod가 던지고, .catch(errorResponse())가 삼켜 콘솔에도 남지 않았습니다.

관측된 증상

dev에서 백엔드와 함께 확인했습니다.

  • 도메인 목록이 항상 "연결된 도메인이 없습니다" — API는 200에 1건을 정상 반환
  • 도메인 연결 폼이 "요청 처리 중 오류가 발생했습니다" — 서버는 202로 정상 접수했고 승인도 실제로 생성됨

범위 — 네 파일

domains.ts에서 시작해 API 파일 전체를 훑었습니다.

파일 상태 쓰는 화면
domains.ts 봉투 안 벗김 도메인
deployments.ts 봉투 안 벗김 배포
cloudConnections.ts 봉투 안 벗김 인프라 · 내 계정
environment.ts 봉투 안 벗김 환경변수
auth.ts 스키마가 봉투를 직접 모델링 — 정상
나머지 unwrapApiData 또는 body.data — 정상

auth.ts가 왜 멀쩡한지가 힌트였습니다. 거기는 스키마 자체가 {status, code, message, data} 형태라 봉투를 그대로 파싱해도 맞습니다.

백엔드가 dev에 직접 찔러 세 엔드포인트 모두 같은 봉투임을 확인했고, 이것이 추측이 아니라 전역 규칙임도 확인해 줬습니다 — ApiResponseAdvicecom.example.dvely 전체를 감싸고, 예외는 WebhookController·PreviewGatewayController(클래스 단위), AuthController#githubAppCallback, AgentController의 SSE 스트림뿐입니다.

고친 방식

unwrapApiDatautils/response로 올려 네 파일에 적용했습니다. 봉투일 때만 벗기고 아니면 그대로 통과하므로, 네 파일 모두 최상위 data 필드를 가진 스키마가 없는 이상 어느 쪽이든 안전합니다(확인함).

agent.ts의 이벤트 목록 조회도 body.data 직접 접근에서 unwrapApiData로 바꿨습니다. 백엔드 문서에 "agent는 직접 반환"이라 적혀 있어 확인이 필요했는데, 실제 raw는 SSE 스트림 하나뿐이라 동작 변화는 없고 방어적 정리입니다.

projects.ts·chat.tsbody.data 직접 접근 17곳은 그대로 뒀습니다. 그 컨트롤러들은 raw 목록에 없어 현재 형태가 맞고, 동작하는 코드를 균일성만으로 건드릴 이유가 없습니다. 백엔드가 그쪽에 @RawApiResponse를 붙일 계획은 없으며 생기면 먼저 알리기로 했습니다.

함께: 조용한 실패에 흔적 남기기

개발 모드에서 스키마 파싱 실패를 console.warn으로 남깁니다. 사용자에게 보이는 메시지는 그대로입니다.

같은 부류를 오늘만 세 번 겪었습니다 — 도메인 목록, 프로젝트 개요(domainSummary), 활동 이력(type enum). 매번 서버는 200이라 서버 로그에는 흔적이 없고, FE 콘솔도 조용해서 원인을 찾는 데 매번 양쪽이 붙어 갈래를 갈라야 했습니다. 백엔드가 제안한 대응입니다.

배포 순서

선행 의존 없습니다. 서버 쪽 변경이 필요 없는 순수 FE 파싱 수정입니다.

bun run typecheck / lint / build 통과.

🤖 Generated with Claude Code

dldnsgkr and others added 3 commits August 19, 2026 21:12
domains / deployments / cloudConnections / environment 네 파일이
succesResponse 결과를 그대로 스키마에 넘기고 있었다. succesResponse 는
axios 바디, 즉 API 봉투({status, code, message, data})를 돌려주므로
배열이나 도메인 객체를 기대하는 스키마에 봉투가 들어가 parse 가 던졌고,
.catch(errorResponse()) 가 삼켜 콘솔에도 안 남았다.

관측된 증상:
- 도메인 목록이 항상 "연결된 도메인이 없습니다" (API 는 200 에 1건)
- 도메인 연결 폼이 "요청 처리 중 오류" (서버는 202 로 정상 접수)

deployments / cloudConnections / environment 는 같은 형태이고 각각 배포·
인프라·환경 화면에서 쓰인다. 세 파일 모두 최상위 data 필드를 가진 스키마가
없어 unwrapApiData 는 봉투일 때만 벗기고 아니면 무해하다.

- unwrapApiData 를 utils/response 로 올리고 네 파일에 적용한다
- 개발 모드에서 스키마 파싱 실패를 console.warn 으로 남긴다. 서버는 200 인데
  화면만 비는 사고가 오늘만 세 번이었고(도메인 목록·프로젝트 개요·활동 이력)
  매번 조용히 삼켜져 원인을 찾는 데 시간이 걸렸다

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
AgentController 는 클래스가 아니라 메서드 하나만 봉투 없이 내려간다. 어느
메서드인지 확정되기 전이라, body.data 를 직접 읽던 이벤트 목록 조회를
unwrapApiData 로 바꾼다. 봉투면 벗기고 raw 면 그대로 통과하므로 어느 쪽이든
맞는다.

projects / chat 의 body.data 직접 접근은 그대로 둔다. 백엔드가 확인해 준
raw 목록(WebhookController · PreviewGatewayController · AuthController
githubAppCallback · AgentController 메서드 하나)에 그 컨트롤러들은 없다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dldnsgkr
dldnsgkr merged commit 4fe1ef6 into main Aug 19, 2026
1 check passed
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