LabHub

디버깅 실전 · 증상에서 원인으로 · 이론

문서와 코드가 다를 때 무엇을 믿는가

LabHub 에서 이어서 보기

한 줄 요약

고객사 코드에서 가장 위험한 결함은 예외를 던지는 코드가 아니라 그럴듯한 값을 조용히 돌려주는 코드다.

왜 이게 필요했나

터지는 버그는 쉽습니다. 트레이스백이 어디가 문제인지 알려 주고, 모니터링이 알람을 울리고, 아무도 그 결과를 신뢰하지 않습니다.

무서운 것은 200 을 반환하는 버그입니다. /sum?a=2&b=3-1 을 돌려주는 API 는 상태 코드가 정상이라 대시보드에서 초록색이고, 로그에도 에러가 없고, 몇 달 뒤 회계 담당자가 숫자가 안 맞는다고 말할 때 발견됩니다. 그때쯤이면 잘못된 값이 이미 하류 시스템 여러 곳에 복제돼 있습니다.

FDE 가 고객사에서 넘겨받는 코드는 대개 이런 상태입니다. 원래 만든 사람은 퇴사했고, 테스트는 없고, 문서는 있지만 코드와 다릅니다.

어떻게 동작하나

문서와 코드가 다를 때 무엇을 믿어야 할까요. 답은 둘 다 믿지 않고 관측된 동작을 믿는 것입니다. 다만 문서는 버리지 않습니다. 문서는 "원래 의도" 를 알려 주는 유일한 단서이고, 코드와 문서가 어긋나는 지점이 곧 버그 후보 목록이기 때문입니다.

실무 절차는 이렇습니다.

1. 사양을 입출력 표로 옮긴다. 문서에 적힌 것을 "이 입력이면 이 출력" 형태로 몇 줄 적습니다. 문서에 없으면 고객에게 묻습니다. 이 표가 없으면 무엇이 버그인지 판정할 기준이 없습니다.

2. 경계값을 넣어 본다. 0, 음수, 원소 한 개, 빈 값, 필수 파라미터 누락. 결함은 대부분 평균적인 입력이 아니라 경계에서 드러납니다. avg 가 원소 세 개에서는 맞고 한 개에서는 틀리다면 나누는 수를 잘못 쓴 것입니다.

3. 실패의 종류를 구분한다. 잘못된 요청에 500 을 돌려주는 것과 400 을 돌려주는 것은 완전히 다른 문제입니다. 400 은 "네가 잘못 보냈다", 500 은 "내가 처리하다 망가졌다" 입니다. 이 구분이 무너지면 하류의 재시도 로직이 오작동합니다. 클라이언트는 5xx 를 재시도 대상으로 보기 때문에, 영원히 실패할 요청을 무한히 재시도하게 됩니다.

4. 데이터가 개입하는 지점을 의심한다. 코드는 맞는데 입력 데이터에 깨진 행이 하나 섞여 있어서 전체가 죽는 경우가 아주 흔합니다. 사양에는 "유효하지 않은 행은 건너뛴다" 고 적혀 있는데 코드에는 그 분기가 없는 식입니다.

현장에서 만나는 모습

넘겨받은 배치 스크립트가 "데이터가 늘어서 느려진 것 같다" 는 고객의 추측과 함께 도착하는 일이 자주 있습니다. 열어 보면 느린 게 아니라 아예 죽고 있고, 원인은 데이터가 늘어난 것이 아니라 새로 들어온 데이터에 처음 보는 형태의 행이 섞인 것입니다.

여기서 FDE 의 판단이 갈립니다. 그 행을 지우고 넘어가면 다음 주에 같은 일이 반복됩니다. 사양대로 건너뛰도록 고치고, 건너뛴 행을 로그로 남기게 만들면 다음번에는 원인이 1분 만에 나옵니다.

고객의 추측을 정면으로 부정할 필요는 없습니다. 검증 목록에 넣고 함께 확인하면 됩니다. 고객의 가설을 문전에서 기각하면, 다음 장애에서 그 사람은 관찰을 말해 주지 않습니다.

다음 실습에서 할 것

인수인계 없이 넘겨받은 계산 API 를 상대로, 문서에 적힌 사양과 실제 동작을 대조해 네 개의 결함을 찾아 고치고, 잘못된 요청에 올바른 상태 코드가 나가도록 만듭니다.