Sentry 에러 수집 사각지대 해소
NFT 전송에만 붙어 있던 Sentry를 전체 API·인증 흐름으로 넓히고, 잡을 에러와 버릴 에러의 기준을 세움.
상황
Sentry가 NFT 전송 흐름에만 붙어 있어 인증·토큰 갱신·브릿지·API 네트워크 에러는 대부분 조용히 사라졌습니다. 잡힌 이벤트조차 전부 anonymous라 어떤 사용자가 겪었는지 알 수 없었고, 루트 렌더 에러가 나면 빈 화면만 뜨고 로그는 0건이었습니다.
원인 분석
어디서 잡고 어디서 버릴지에 대한 기준(캡처 정책)이 없었습니다. 5xx는 백엔드 Sentry와 중복될 우려가 있고, 모바일의 일시적인 네트워크 끊김 노이즈가 진짜 장애 시그널과 섞였으며, 토큰 갱신 흐름의 조용한 복구 코드(.catch(() => null))가 시그널을 삼키고 있었습니다. Sentry.setUser를 부르는 곳도 없었습니다.
시도 · 트레이드오프
중복 캡처를 막으려고 처음엔 에러 객체에 마커(Symbol)를 심는 방식을 썼습니다. 그런데 마커를 심는 코드와 확인하는 코드가 6곳에 흩어지고, 새 흐름이 추가될 때 마커를 잊으면 다시 중복이 생기는 구조라 접었습니다. 대신 캡처는 에러가 최종 소멸하는 한 곳에서만 하고, 거쳐온 경로는 breadcrumb으로 남기는 방식으로 바꿨습니다.
해결
상황별 기준부터 세웠습니다. 5xx는 백엔드 Sentry에 맡기고, 401·403·404처럼 화면에서 이미 처리되는 에러는 버리고, 타임아웃·레이트 리밋은 warning으로, 백엔드가 못 보는 네트워크·파싱 에러는 잡고, 오프라인·요청 취소는 건너뜁니다. 이 기준을 React Query 글로벌 핸들러에 넣어 모든 API 호출이 자동으로 걸리게 하고, 로그인·토큰 갱신·로그아웃 시점마다 Sentry.setUser를 동기화해 모든 이벤트에 사용자 id가 붙게 했습니다. 루트 렌더 에러용 global-error.tsx를 추가하고, 11개 시나리오를 원클릭으로 돌려보는 테스트 페이지(/test/sentry)도 만들었습니다.
결과 · 배운 점
NFT 전송만 보이던 관찰 범위가 전체 API 호출로 넓어졌고, 모든 이벤트에서 어떤 사용자가 겪었는지 바로 확인할 수 있게 됐습니다. 한 사건이 최대 3건씩 중복으로 찍히던 것이 1건으로 정리됐고, Sentry 관련 코드를 고쳐도, 잡혀야 할 것과 안 잡혀야 할 것이 여전히 맞게 동작하는지 30초 안에 다시 확인할 수 있습니다.