Repository navigation
refactor(core,afternote): ErrorReporter 채택 — Logcat 에만 남는 실패 16곳 분류 #962
Description
#928 에서 분할된 이슈다. 인프라 전제·제약·판단 기준을 아래에 그대로 복제해 두었으니 이 이슈만 보고 진행하면 된다. 다른 모듈은 건드리지 않으므로 나머지 두 이슈와 파일이 겹치지 않는다.
배경
Result.failure 로 흡수되는 실패는 Crashlytics 자동 수집(uncaught 예외)에 잡히지 않는다. ErrorReporter 를 거쳐 명시적으로 기록해야 릴리즈에서 보인다.
app·feature/onboarding·feature/afternote/presentation 은 이미 채택이 끝났다(30곳). 남은 것이 Log.e/Log.w 로 Logcat 에만 찍고 끝나는 20곳이고, 그중 16곳이 이 이슈 몫이다.
인프라 — 새로 만들 것이 없다
ErrorReporter를 생성자에 주입하면 끝이다. 정책(코루틴 취소 제외·예외 문구 redact)은 인터페이스가 이미 지킨다 — 호출부에서 다시 거를 필요 없다- 실제 Crashlytics 결선은
app의ErrorReportingModule에만 있다 — 이 모듈에 Firebase 의존을 추가하지 않는다. 주입받는 타입은 항상ErrorReporter추상이다 - stage 어휘는 모듈마다 따로 둔다(도메인 어휘라서 의도된 분산이다). 선례 3개:
HomeFailureReporting.kt—appAfternoteFailureReporting.kt—feature/afternoteAuthFailureReporting.kt—feature/onboarding
제약 — 일괄 치환 금지
Crashlytics 는 non-fatal 을 최근 8건만 보관하고 초과분을 오래된 것부터 버린다 (코드 근거 · Firebase 문서).
전부 recordFailure 로 갈아끼우면 네트워크가 한 번 끊길 때 잡음이 한도를 채워 실제 장애를 밀어낸다. 이 작업은 "어떤 실패가 텔레메트리 가치가 있는가" 를 골라내는 분류이지 치환이 아니다.
판단 기준
- 승격(ErrorReporter) — 사용자 작업이 실패했고 서버·기기 문제가 의심되며, 재현이 어려워 실기 QA 로 못 잡는 것 (저장 실패, 세션 만료, 업로드 실패)
- 유지(Logcat) — 개발 중 흐름 추적용이고 정상 경로에서도 발생 가능한 것 (지문 인증 취소 등)
- 삭제 — 이미 상위에서 처리되어 중복이거나, 디버깅이 끝난 흔적
승격한 지점은 어느 단계에서 깨졌는지 구분할 stage 속성을 함께 넘긴다. 개인정보·자격증명은 넣지 않는다.
작업 — 16곳 분류
각 지점을 승격 / 유지 / 삭제 로 분류하고 반영한다.
core/network — 5곳
TokenReissuer 는 errorReporter.recordFailure() 를 제대로 쓰는데 같은 패키지의 TokenAuthenticator 는 전부 Log.e 로만 찍는다. core 에는 stage 어휘 파일이 없다 — TokenReissuer 처럼 recordFailure 를 직접 호출하고 stage 를 속성으로 넘기면 된다.
-
TokenAuthenticator.kt- L26 — 재시도 3회 초과, 세션 만료 처리
- L38 — 직전 요청에 토큰 없음
- L51 — 리이슈 실패(서버가 동일 토큰 반환)
- L60 — 리이슈 인증 거절, 세션 만료 처리
- L66 — 리이슈 일시 실패, 세션 유지·요청 중단
core/data — 1곳
-
UserRepositoryImpl.kt#L148— 탈퇴 후 세션 정리 실패
feature/afternote/presentation — 9곳
이 모듈은 AfternoteFailureStage 가 이미 있다 — 승격 시 stage 를 추가하고 recordAfternoteFailure 를 쓴다.
-
AfternoteEditorViewModel.kt— L325(썸네일 업로드 실패), L501(편집용 기존 데이터 로드 실패), L540handleSaveFailure— 저장 실패인데 Logcat 뿐이다- 참고: 바로 옆 L326·L502·L541 은 이미
recordAfternoteFailure를 호출한다. 중복인지 확인하고 중복이면Log.e쪽을 삭제로 분류한다
- 참고: 바로 옆 L326·L502·L541 은 이미
-
AddSongViewModel.kt#L63— 곡 검색 실패 (L64 에 이미MUSIC_SEARCH승격 있음) -
MemorialVideoUpload.kt#L202— 추모 영상 업로드 -
BiometricAuth.kt— L101Log.w(인증 오류·사용자 취소 포함 가능 → 유지 후보), L120Log.e(BiometricPrompt 초기화 실패) -
PlaylistSongItem.kt#L124 -
MemorialPlaylist.kt#L225
feature/afternote/data — 1곳
-
AfternoteRepositoryImpl.kt#L120— 공용 실패 로깅 헬퍼다. 호출부가 여럿이라 여기서 승격하면 한도를 빠르게 소모할 수 있다 — 헬퍼가 아니라 호출부 단위 승격이 맞는지 함께 판단한다
완료 조건
- 16곳 전부 승격/유지/삭제 중 하나로 분류되어 반영
- 승격 지점에 stage 속성이 붙어 있다
-
core모듈에 Firebase 의존이 추가되지 않았다 - 승격 지점 중 판정 로직이 생긴 곳은 단위 테스트로 덮는다 (선례)
Activity
Merge pull request #1319 from Afternote/refactor/962-error-reporter-a…
github-actions commentedon Aug 28, 2026
Auto-closed by merge of #1319 into
fix/584-actions-template-prefill.