Repository navigation
refactor(setting): 서비스 알림 실패를 분류하고 저장 실패를 ErrorReporter로 기록한다 #963
Description
작업 유형
refactor — 동작 변경 없는 구조·책임·경계 개선
주 담당 모듈
setting — 설정
개요
#928에서 분리한 ErrorReporter 채택 작업 중 설정 몫을 추적한다. 기존 본문에 함께 있던 타임레터 실패 분류·계측은 https://github.com/Afternote/Afternote-FE/issues/2040로 옮겼다. 이 이슈의 완료는 설정 범위에 한정한다.
Result.failure로 처리한 실패는 uncaught crash 자동 수집으로 남지 않는다. 다만 기존 로그를 모두 non-fatal로 승격하면 빈번한 조회 실패가 사용자 저장 실패 진단을 밀어낼 수 있으므로, 사용자 작업 실패·개발자 진단·중복 기록을 구분한다.
기존 4곳과 현재 구현
원래 실측(6123a68af7295622222a98a4e09b9f4570e419ff)은 PushNotificationViewModel의 조회 실패 1곳과 뉴스레터·마음의 기록·애프터노트 토글 저장 실패 3곳이었다. 이후 설정 MVI·저장 책임 정리로 3개 토글이 공통 저장 경로에 수렴했다. 이전 콜백 3벌을 다시 만들지 않고 현재 production 경계에서 기록한다.
| 원래 대상 | 분류와 현재 동작 |
|---|---|
loadPushSettings 조회 실패 |
Logcat 유지. 기존 조회 오류·재진입 상태 보존 계약 유지 |
| 뉴스레터 토글 저장 실패 | ErrorReporter 승격. stage=push_setting_update, push_setting=newsletter |
| 마음의 기록 토글 저장 실패 | 같은 stage, push_setting=mind_record |
| 애프터노트 토글 저장 실패 | 같은 stage, push_setting=afternote |
현재 추가된 마케팅 동의 조회도 조회 실패 분류에 맞춰 Logcat에 유지한다. SMS·이메일·푸시 마케팅 동의 저장 계측은 선행 코드에 이미 있으므로 재작성하지 않는다. 조회 취소 전파의 마지막 잔여는 #1501에서 별도로 처리한다.
검토된 설정 구현: 583ebee2c637cbdb45c573e191f9b23d5cb69555 (fix/963-setting-error-reporting), 실제 base f7eeb80fa52a9d8992c571390d2cecc7e4fd964a (handoff/1920-setting-1hyok, PR #1930). 변경은 PushNotificationViewModel과 해당 테스트 2개 파일이며 타임레터 코드는 포함하지 않는다. 커밋 존재를 원격 머지 완료로 간주하지 않는다.
보존할 제약
- 기존
core:common의ErrorReporter주입과 app의ErrorReportingModule바인딩을 사용한다. feature에 Firebase 의존성을 추가하지 않는다. - 호출은
recordFailure를 통해 취소 제외·예외 메시지/cause redaction 정책을 적용한다. 이메일·토큰·사용자 식별자 같은 개인정보나 자격증명을 속성에 넣지 않는다. - 도메인 작업 단계와 최소 고정 속성만 기록하고, 사용자 안내 문구·재시도·모달·저장 성공/실패 상태 계약을 바꾸지 않는다.
- 원문이 근거로 삼은 Crashlytics non-fatal 최근 8개 보관 한도를 고려해 반복 조회 잡음을 승격하지 않는다. 개발 중 예상 실패는 Logcat 유지, 기존 처리 경로와 중복되는 로그는 중복 여부를 확인한 뒤 정리한다.
완료 조건
- 기존 설정 4곳의 분류를 위 표와 현재 코드에 일치시킨다.
- 3개 서비스 알림 토글의 실제 저장 실패는 공통 stage와 토글 속성으로 각각 1회 기록한다.
- 조회 실패·성공·취소는 새 저장 실패 진단을 남기지 않으며 기존 토글 복원·오류 상태 동작을 보존한다.
- 테스트로 3개 토글의 속성·실패 복원 및 성공/취소/조회 비계측을 검증하고 관련 검사를 통과한다.
- feature의 Firebase 직접 의존성은 0건이다.
참고
- 분리 전 범위: ErrorReporter 채택 범위 정리 — 실패 20곳이 Logcat 에만 남는다 #928 → refactor(setting): 서비스 알림 실패를 분류하고 저장 실패를 ErrorReporter로 기록한다 #963(설정·타임레터). 타임레터 잔여: refactor(timeletter): handled 실패를 분류하고 필요한 ErrorReporter 계측을 추가한다 (#963 분리) #2040.
- 취소 계약 후속: fix(setting): ViewModel 저장소 호출의 취소 전파 잔여를 마무리한다 (#661 후속) #1501. 설정 선행 스택: refactor: 설정 MVI와 저장·Repository 책임을 최종 계약으로 통합 (#1502) #1967 → fix(setting): 오류 상태 처리를 안정화한다 (#708) #1925 → fix(setting): 설정 하위 화면 4종의 재진입 갱신 (#1920) #1930.
- 기존 공통 계약:
core/common/src/main/kotlin/com/afternote/core/common/reporting/ErrorReporter.kt. - 분류 선례:
app/.../reporting/HomeFailureReporting.kt,feature/afternote/.../reporting/AfternoteFailureReporting.kt,feature/onboarding/.../reporting/AuthFailureReporting.kt(6123a68af7295622222a98a4e09b9f4570e419ff기준). - 원문 문서 근거: Crashlytics 보고서 맞춤설정.
Activity
[-]refactor(setting,timeletter): ErrorReporter 채택 — 설정 Log.e 4곳 분류·타임레터 계측 신설[/-][+]ErrorReporter 채택 — 설정 Log.e 4곳 분류·타임레터 계측 신설[/+][-]ErrorReporter 채택 — 설정 Log.e 4곳 분류·타임레터 계측 신설[/-][+]refactor(setting): 서비스 알림 실패를 분류하고 저장 실패를 ErrorReporter로 기록한다[/+]github-actions commentedon Sep 13, 2026
이 이슈를 맡은 PR 은 #2042 다 (base
handoff/1920-setting-1hyok).base 가 기본 브랜치(
develop)가 아니라서 GitHub 은 이 이슈의 Development 칸에아무것도 표시하지 않는다. 본문에
Closes #N이 있어도 마찬가지다 — 그 링크는 기본 브랜치를target 하는 PR 에서만 만들어진다.
PR 이 닫히거나 머지되면 이 이슈의
pr-open라벨은 다음 리컨사일에서 떨어진다.github-actions commentedon Sep 23, 2026
이 이슈를 맡은 PR 은 #2147 다 (base
fix/1501-current-setting-cancellation).base 가 기본 브랜치(
develop)가 아니라서 GitHub 은 이 이슈의 Development 칸에아무것도 표시하지 않는다. 본문에
Closes #N이 있어도 마찬가지다 — 그 링크는 기본 브랜치를target 하는 PR 에서만 만들어진다.
PR 이 닫히거나 머지되면 이 이슈의
pr-open라벨은 다음 리컨사일에서 떨어진다.chore(setting): propagate current setting parent (#963)
test(setting): propagate save error viewport check (#963)