운세 구절 조회가 운영 환경에서 목 데이터를 내려보내던 버그 수정
목차
두 파일을 건드려서 꽤 조용한 것 같아 보이지만, 사실 상당히 미묘한 환경 분기 버그를 잡은 작업이었다.
배경: "운영 환경인데 왜 mock이 뜨지?"
앱을 운영 백엔드에 직결해서 테스트하는 상황이 있었다. 로컬 개발 편의를 위해 일부 API 호출에 mock 클라이언트를 끼워두는 패턴은 흔한데, 문제는 이 mock 분기가 환경 플래그가 아니라 요청 실패 여부에 연동되어 있었다는 거다.
구조를 단순화하면 이런 흐름이었다:
// 문제가 됐던 흐름 (단순화)
Future<Verse> fetchVerse(String id) async {
try {
final res = await _client.get('/additional/$id'); // 부가 요청
return Verse.fromJson(res.data);
} catch (e) {
// 실패 시 fallback — 여기서 mock 클라이언트가 끼어들었음
return _mockClient.fetchVerse(id);
}
}
부가 요청(additional request)이 어떤 이유로든 실패하면 mock fallback이 타게 설계되어 있었고, 그 mock fallback이 구절(verse) 조회까지 오염시켰다. 즉 부가 요청 실패 → mock 경로 진입 → 이후 구절 조회도 mock 데이터로 응답이라는 연쇄가 일어났다.
운영 환경에서 부가 요청이 일시적으로 실패하거나, 아예 해당 기능이 미지원 상태일 때 구절 조회까지 mock으로 내려가는 건 사용자에게 가짜 데이터를 보여주는 것과 같다. 발견이 늦어졌다면 조용히 운영 이슈로 퍼질 수 있는 케이스였다.
실제 수정 방향
변경이 일어난 두 파일의 역할을 보면:
| 파일 | 역할 | 이번 변경 의미 |
|---|---|---|
app/lib/data/api_client.dart |
HTTP 클라이언트 추상화 / 실제 요청 처리 | mock 분기 조건 수정 또는 제거 |
app/lib/main.dart |
앱 진입점, 의존성 주입 / 환경 초기화 | 운영 환경 직결 플래그 정리, mock 클라이언트 주입 경로 명확화 |
main.dart에서 환경에 따른 클라이언트 주입을 명시적으로 분리하고, api_client.dart에서 부가 요청 실패가 구절 조회 경로에 영향을 주지 않도록 책임을 끊는 방식이었을 거다. 핵심은 실패 처리(fallback)와 mock 사용 여부를 직교하는 관심사로 분리하는 것.
// 수정 후 방향 (개념)
// main.dart: 환경 플래그로 클라이언트 결정
final apiClient = isProduction
? RealApiClient(baseUrl: prodUrl)
: MockApiClient();
// api_client.dart: 부가 요청 실패는 null/empty로 처리, mock 연동 X
Future<AdditionalData?> fetchAdditional(String id) async {
try {
return await _realClient.get('/additional/$id');
} catch (e) {
return null; // 실패 = null, mock 아님
}
}
fallback을 "mock으로 교체"가 아니라 "없음(null) 또는 기본값 반환"으로 처리하면, 구절 조회 같은 별개의 API는 영향을 받지 않는다.
회고
이런 버그는 개발 초기에 "편의상 mock을 fallback으로 쓰자"는 결정이 나중에 환경 경계를 흐리는 식으로 발목을 잡는 전형적인 사례다. 팀 리뷰 때 mock 사용 범위를 명시적 환경 플래그로만 제한하자는 가이드를 공유했다.
- mock은 주입 시점(main/DI 레이어)에서만 결정
- 런타임 실패를 mock 트리거로 쓰는 패턴은 지양
- 부가 기능 실패는 핵심 기능 경로와 독립적인 fallback으로 처리
사실 api_client.dart와 main.dart 두 파일이면 변경 규모는 작아 보이지만, 이 두 파일이 앱의 환경 분기와 네트워크 계층 전체를 결정하는 파일이라 영향 범위는 전체 API 호출에 걸친 셈이다. 핀포인트 수정이 맞지만, 해당 포인트가 아키텍처적으로 꽤 중심에 있었다.
다음엔 이 mock 분기 패턴을 팀 내 코드리뷰 체크리스트에 항목으로 추가할 것 같다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.