Search

[Tip] 체계적 디버깅: 에러 메시지 읽기와 가설 검증

문제 의식

왜 우리는 에러 메시지를 읽어야 한다는 걸 알면서도, 정작 에러 상황이 되면 에러 메시지를 열심히 읽지 않을까요?
왜 디버깅 시 무작정 코드를 수정하며 토끼굴에 빠지게 될까요?

핵심 원칙: No 가설, No 디버깅

디버깅 시 증상을 모호하게 두면 루프를 돌면서 가설-실험 사이에서 학습이 일어나지 않아 무지성 console.log, 수정 무한 루프에 빠진다
점진적 심화(progressive deepening) 이론: 인간의 작업 기억 용량 한계 때문에 깊이 탐색을 한번에 길게 하기 보다는 여러 번 왕복하면서 조금씩 더 깊이 파고드는 방식이 효과적

기대되는 행동 변화

"에러 메시지 읽기"와 "가설 수립"이라는 행동을 보다 세부적으로 쪼개어 연습할 수 있게 된다
Before:
에러 메시지에 압도되어 전체를 복사해 구글에 붙여넣는다
의미를 파악하기보다 코드에 랜덤한 변경을 가하며 막연히 해결되길 기도한다
디버깅 과정에 대한 메타인지가 없어 현재 무엇을 시도하는지 / 해야 하는지 막연하다
After:
에러 메시지를 단서로 삼아 체계적으로 원인을 분석한다
'무엇이, 어디서, 왜' 발생했는지 파악하고, 이를 바탕으로 정확한 해결책을 찾거나 효과적인 검색어를 만든다
"먼저 에러 원인에 대한 가설을 세팅하라"를 떠올리고, 노트 펴고 한 줄 요약부터 시작한다

체계적 디버깅 프로세스

1단계: 정상 동작을 정의한다 (심적 표상)

코드가 정상적으로 동작했을 때 어떤 결과가 나와야 하는지 명확히 정의
예: "로그인 버튼 클릭 → API 호출 → 사용자 정보 저장 → 대시보드로 이동"

2단계: 에러 메시지를 읽는다

문제의 '무엇'과 '어디' 특정하기
에러 타입 식별: TypeError, ReferenceError, SyntaxError 등 에러의 종류가 무엇인지 확인한다
에러 메시지 읽기:
에러가 '무엇'에 대해 불평하는지(ex: Cannot read properties of undefined) 핵심 메시지를 파악한다
복잡해 보이는 메시지라도, 포기하지 않고 "핵심 메시지"를 중심으로 확인하려고 노력한다
GPT를 활용할 경우 문제 해결 대신 에러 메시지의 독해에만 활용한다
발생 위치 추적: 에러 메시지에 명시된 파일 이름과 라인 넘버를 통해 코드의 어느 부분에서 문제가 발생했는지 정확히 찾아낸다
문제의 '왜' 이해하기
해당 코드 분석: 특정된 라인의 코드가 어떤 작업을 하려는지, 어떤 변수를 사용하는지 확인한다
변수 상태 확인: 에러의 원인이 되는 변수가 그 시점에 null, undefined는 아닌지, 혹은 예상과 다른 타입의 값은 아닌지 의심하고 확인한다
호출 스택(Call Stack) 확인: 이 에러가 발생하기까지 어떤 함수들이 순서대로 호출되었는지 파악하여 문제의 맥락을 이해한다

3단계: 문제 상황을 한 문장으로 요약해 정리한다

실패 화면, 에러 메시지를 단 한 문장으로 요약해 노트에 쓴다
예: "로그인 버튼 클릭 시 user 객체의 email 속성을 읽을 수 없다는 TypeError 발생"

4단계: 문제 해결을 위한 가설을 가능성이 높은 순으로 적는다

가설 옆에 원인으로 가능성이 높은 후보 3가지를 적는다
예:
1.
API 응답이 예상과 다른 형태로 왔을 가능성
2.
비동기 처리가 완료되기 전에 접근했을 가능성
3.
초기값 설정이 잘못되었을 가능성

5단계: 각 가설별 검증 방법을 추가한다

각 후보 옆에 확인 방법을 추가한다
변수 값 확인, 네트워크 응답 확인, DOM 상태 확인 등
확인 과정에서 복잡한 절차를 거쳐 값이 확인되어야 하는 경우 콘솔이 아니라 디버거를 활용해야 한다고 추가로 표기한다
디버깅 도구 선택 가이드
단순한 결과물 확인: console.log
로직의 과정을 봐야 하면: debugger break point
네트워크 요청 봐야 하면: Network 탭
DOM 변화 추적: Elements 탭 + break on subtree modifications

6단계: 정상 동작과 문제 상황 사이 차이에 존재하는 원인을 탐색한다

각 가설을 순서대로 검증하며 실제 원인을 찾아낸다
검증 중 새로운 정보가 발견되면 가설을 수정하거나 추가한다

7단계: "예상했던 결과 vs 실제 결과"를 표로 비교한다

검증 항목
예상 결과
실제 결과
차이점
API 응답 형태
{user: {email: ...}}
{data: {user: ...}}
데이터 키 값이 다름

8단계: 문제가 해결될 때까지 각 단계를 오가며 진행한다

점진적 심화 이론에 따라 한 번에 모든 것을 파악하려 하지 말고, 조금씩 깊이 파고든다. 중간중간 내가 어디쯤 와있는지 여러 번 왕복하며 점검한다.
각 검증 사이클마다 새로 알게된 사실을 기록하여 다음 사이클에서 활용한다

Caution & Tips

디버거 사용이 익숙하지 않다면 사용법을 익혀야 함
디버깅 마인드셋 발표 (배휘동님): https://www.youtube.com/watch?v=KkkyYFziOG8
상황 인식: "뇌가 무작정 수정을 시도하고 있다" 감지 시 즉시 멈추고 가설부터 세우기
패턴 매칭: 비슷한 에러를 만났을 때 이전 경험을 활용하되, 맥락의 차이를 항상 고려