Repository navigation
refactor(timeletter): handled 실패를 분류하고 필요한 ErrorReporter 계측을 추가한다 (#963 분리) #2040
Copy link
Copy link
Open
Labels
area:timeletter타임레터 기능 영역타임레터 기능 영역refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업동작 변경 없이 코드 구조·책임·경계를 개선하는 작업
Description
작업 유형
refactor — 동작 변경 없는 구조·책임·경계 개선
주 담당 모듈
timeletter — 타임레터
개요
#928에서 파생한 #963의 타임레터 실패 분류·계측 몫이다. 설정의 조회/3개 토글 분류는 #963에 남긴다. 현재 타임레터 presentation의 handled 실패가 UI 오류나 빈 보조 목록으로 처리되지만 ErrorReporter에는 기록되지 않는 경계 중 실제 진단 가치가 있는 곳을 분류한다.
확인된 기존 실패 경계
실측 기준 develop의 93e983fe1ea9c813a8673a7c59e401a5ea40aabc. 경로 접두사는 feature/timeletter/presentation/src/main/kotlin/com/afternote/feature/timeletter/presentation/viewmodel/다. 예전 #963의 줄번호와 SAVE_FAILED 표기는 현재 아래 production 경계로 대응시키며 옛 구현을 복원하지 않는다.
| 대상 | 현재 처리와 분류 후보 |
|---|---|
TimeLetterWriteViewModel.save |
생성 UseCase 또는 수정 Repository/블록 해석의 결과 실패를 SaveFailed/ServerRejection으로 바꿈. 사용자 저장 실패 진단을 우선 검토 |
같은 파일 loadEditingTimeLetter |
기존 글 조회 실패를 LoadFailed/ServerRejection으로 바꿈. 조회 잡음과 실제 장애의 진단 가치 분류 |
TimeletterViewModel.load, deleteTimeLetter |
목록 조회 오류 / 사용자 삭제 실패 상태. 각각 조회·사용자 작업의 기준으로 분류 |
TimeLetterDetailViewModel.load |
상세 조회 오류. 수신자 보조 조회 실패는 빈 이름 맵으로 낮춤 |
DraftLetterViewModel.loadDrafts, deleteSelected, deleteAll |
임시보관함 조회/삭제 실패. 기존 취소 재던짐과 finally 정리 보존 |
RecipientTimeletterViewModel.load, RecipientTimeLetterDetailViewModel.load |
수신 목록/상세 조회 오류 |
TimeletterViewModel·TimeLetterWriteViewModel의 수신자 보조 조회, 작성기 등록 건수·초안 건수 조회 |
기존 fallback/실패 결과가 이미 존재하는 지점만 분류. 계측을 이유로 새 API·상태·화면을 만들지 않음 |
이 표는 계측 후보 목록이며 모두 승격하라는 요구가 아니다. 실패 계측을 찾으려고 정상 빈 목록이나 입력 검증·사용자 취소를 장애로 취급하지 않는다. 승격하지 않는 경계도 이유를 남기면 된다.
예정 변경과 재작성 경계
- #1692는 생성·수정·등록 게이트의 소유권을 저장 UseCase로 옮긴다. 작성기 내부의 개별 Repository/업로드 경로에 임시 stage 계층을 먼저 만들지 않는다. 기존 UI 저장 결과 경계에 기록을 둘 경우 최종 UseCase 결과에서도 그대로 소비되는지 확인하고, 이동될 경계만 남는다면 #1692와 합쳐 처리한다. 현재 없는 미래 결과 타입·임시 인터페이스는 만들지 않는다.
- 서버 실패가 빈 정상 화면·무음 상태로 수렴 — 목록·수정·임시저장·수신인 선택 복구 수단 부재 #714 / PR fix(timeletter): 서버 실패 상태와 재시도 처리 (#714) #1365 (
a89e102d5ed125c2986efeac27b63d420a271bca)는 편집 대상 로드 실패·재시도와 수신자 목록 상태를 변경한다. 해당 오류 상태에 붙는 계측만 최신 변경 위에서 결정한다. 로딩/오류/재시도 UI를 이 이슈에서 다시 구현하지 않는다. - fix(timeletter): 타임레터 하위 화면 5종의 재진입 갱신 (#703 분리) #1921 / PR fix(timeletter): 타임레터 하위 화면 5종의 재진입 갱신 (#1921) #1905 (
f0cfec520bb5665359c6a168c8cae603e4a04600)는 하위 화면 재진입 시 조회·기존 상태 보존을 변경한다. 자동 갱신 잡음 분류를 최신 load 경계와 맞춘다. 같은 파일이라는 이유만으로 독립 저장 실패 분류까지 차단하지 않는다. - #1501에서 분리한 https://github.com/Afternote/Afternote-FE/issues/2041는 목록/상세의 취소 전파 잔여를 담당한다. ErrorReporter 자체도 취소를 제외하므로 두 이슈 사이에 무조건적인 선행 관계를 만들지 않는다.
보존할 제약과 완료 조건
- 사용자 저장·삭제 등 실기 진단이 필요한 실패, 조회 잡음, 정상 입력 검증/취소, 중복 계측을 분류하고 선택 근거를 남긴다.
- 승격한 경계만 기존 ErrorReporter의
recordFailure를 호출한다. stage는 타임레터의 실제 도메인 작업 어휘로 정하고, 필요하다면TimeLetterFailureStage등 현재 호출자가 소비하는 최소 표현으로 정리한다. 승격 0곳이면 근거만 남기며 사용하지 않는 stage 타입을 만들지 않는다. - 취소 제외·예외 메시지/cause redaction을 유지하며 사용자 식별자·수신자 이름·편지 내용·URL·토큰 등 개인정보/자격증명을 속성에 싣지 않는다.
- 성공·입력 검증·취소의 비계측과 선택한 실패의 단계/중복 기록 방지를 실제 소비 경로로 검증한다.
- 기존 UI 상태·저장/등록 게이트·재시도·삭제·업로드 정책을 보존한다. 구독 한도·압축·이미지 삭제 등 새 제품 정책은 추가하지 않는다.
-
core:common의 기존 주입 계약과 app 바인딩을 사용하며 feature의 Firebase 직접 의존성은 0건이다. 관련 단위 테스트·ktlint 및 영향받는 앱 컴파일을 통과한다.
참고
- 분리 원본 refactor(setting): 서비스 알림 실패를 분류하고 저장 실패를 ErrorReporter로 기록한다 #963, 최초 추적 ErrorReporter 채택 범위 정리 — 실패 20곳이 Logcat 에만 남는다 #928. 이 이슈를 완료해도 다른 모듈의 계측 확대를 완료한 것으로 보지 않는다.
- 기존 계약/선례:
core/common/.../reporting/ErrorReporter.kt,app/.../reporting/HomeFailureReporting.kt, afternote/onboarding의*FailureReporting.kt. - 원문이 보존한 기준: Crashlytics non-fatal 보관 한도와 맞춤설정. 반복 조회 잡음이 중요한 사용자 실패 진단을 밀어내지 않도록 선택한다.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:timeletter타임레터 기능 영역타임레터 기능 영역refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업동작 변경 없이 코드 구조·책임·경계를 개선하는 작업
Activity