|

AI 코딩 앱에서 ‘성공한 빈 응답’을 실패로 다뤄야 했던 이유

이 글은 드라이브라디오 개발 기록을 바탕으로 한 사례입니다. 결론부터 말하면, 외부 API 호출이 예외를 던지지 않았다고 해서 사용자에게 정상 경험이 제공된 것은 아닙니다. 이 프로젝트에서는 음악 추천 API가 오류나 타임아웃 없이 빈 배열을 돌려주는 경우가 실제 원인이었습니다.

문제: 음악이 있어야 할 구간에 폴백 음원이 나왔다

드라이브라디오는 위치 기반 이야기와 음악을 교차 편성합니다. 처음에는 추천 검색이 실패하면 예외 처리와 재시도로 대응했습니다. 그런데 현장 로그를 회수해 보니, 한 출근길 세션의 25회 검색 중 7회가 오류 없이 결과 0건으로 끝났습니다. 타임아웃은 0회였고, 결과가 있는 검색은 재생 후보도 정상으로 확인됐습니다.

즉 기존 코드는 “예외가 없으므로 성공”으로 처리했고, 다음 단계에서 후보가 없다는 이유로 폴백 음원으로 내려갔습니다. 사용자 관점에서는 음악 서비스가 멀쩡한데도 첫 코너에 엉뚱한 소리가 나오는 현상이었습니다.

수정: 예외가 아니라 상태 계약을 바꿨다

  1. 검색 결과가 0건이면 실패 상태로 분류하고 재검색한다.
  2. 재검색도 비면, 세션에서 직전에 확보한 재생 가능 후보 풀을 먼저 사용한다.
  3. 후보 풀도 없을 때만 폴백 음원을 사용한다.
  4. 각 경로에 결과 수, 재시도 여부, 후보 풀 사용 여부를 기록한다.

핵심은 API 호출 성공 여부가 아니라 “다음 코너에 실제로 재생 가능한 곡이 있는가”를 성공 조건으로 삼은 점입니다. 백업 풀은 최근 재생 곡과 직전 곡을 제외해 반복도 줄이도록 했습니다.

남긴 교훈

외부 서비스 통합에서 성공한 빈 응답은 가장 놓치기 쉬운 실패입니다. 예외 처리만 촘촘히 만드는 대신, 사용자가 기대하는 최종 산출물 기준으로 상태를 계측해야 합니다. 이 사례의 다음 검증 항목도 남아 있습니다. 실제 운전 세션에서 재검색과 백업 풀이 폴백 사용 빈도를 얼마나 낮추는지, 그리고 음악 구독 상태별 동작이 같은지를 계속 확인해야 합니다.

이 글은 특정 서비스의 성능을 일반화하지 않습니다. 한 iOS 앱의 현장 로그와 수정 기록에서 얻은 운영 원칙을 정리한 것입니다.