Silent Fail 박물관
디버깅에서 가장 무서운 건 시끄러운 에러가 아닙니다. 조용한 실패(silent fail) 입니다. 에러 메시지조차 안 뜨고, 그냥 기능이 안 되는 것. 우리가 모은 silent fail들을 박물관처럼 전시해 봅니다 — 전부 "한 줄"이 전체를 죽인 사례입니다.
전시 1 — 진단조차 안 보이는 진단
HUD(화면 정보 표시)가 통째로 안 그려졌습니다. 원인을 찾으려 진단 print를 봤는데 — 그 진단 print 자체에 변수 오타가 있었고, 그게 거대한 try/except: pass에 먹혀 조용히 사라졌습니다. 진단하려고 심은 코드가 진단을 막은 셈입니다.
도식 렌더링 중…
전시 2 — 아무것도 안 하는 함수
로봇팔 정밀도가 316mm로 고정돼 있었습니다. PD 게인을 아무리 바꿔도 안 변했습니다. 원인 — 게인을 설정하는 함수가 silent no-op(조용히 아무것도 안 함)였습니다. 호출은 됐지만 실제로는 무시됐고, 에러도 없었습니다. PD를 바꾸는 모든 시도가 영원히 헛수고였던 것입니다.
전시 3 — 빈 dict가 참(truthy)이라서
수상정(USV)이 z=-578m로 가라앉았습니다. 원인 — 어떤 설정이 빈 dict {} 였는데, 빈 dict가 참으로 평가되면서 "이 값이 있다"고 잘못 판정 → 수상정이 수중 체계 경로를 타고 침몰했습니다. 비어 있는 걸 "있음"으로 본 한 줄이었습니다.
⚠️
{}·None·"" 같은 falsy의 함정 — "값이 있으면" 같은 조건은 빈 컬렉션·None·빈 문자열에서 의도와 다르게 동작합니다. 존재 검사는 명시적으로(is not None, 길이 체크) 해야 합니다.
공통 범인 — "조용히 넘어가기"
세 전시의 공통점은 하나입니다 — 실패를 에러로 드러내지 않고 조용히 넘어간 것.
도식 렌더링 중…
💡 fail-loud가 디버깅의 90% — 실패하면 에러를 반환하고 traceback을 찍어야 합니다. "A가 안 되면 조용히 B로" 같은 fallback은 문제를 숨길 뿐입니다.
except는 traceback을 명시 출력하고, 수렴 실패 시 명령을 silent skip 하지 마세요. 에러가 시끄럽게 터지면, 원인은 이미 절반 잡힌 것입니다.
⚠️ "Non-critical" 주석을 경계하라 — "이건 중요하지 않으니 실패해도 넘어감"이라 적힌 분기가, 사실은 전체를 죽이는 root cause인 경우가 많습니다. 부력 한 줄이 함대를 가라앉혔듯, "non-critical"이 critical이었습니다.
한 줄 정리
📌 가장 무서운 버그는 시끄러운 에러가 아니라 silent fail — 진단 오타가 try/except에 먹히고, 함수가 silent no-op이고, 빈 dict가 참이 되는 한 줄들이 전체 기능을 죽인다. fail-loud(실패=에러+traceback)가 디버깅의 90%이며, "조용히 넘어가기"와 "non-critical" 주석을 경계하라.
