Repository navigation
refactor(core): 인증·계정 예외 6종을 CoreAuthFailure sealed 루트로 압축 (#934 1·2단계) [base: develop] - #1051
Merged
Merged
Conversation
core:domain 에 흩어져 있던 5개와, onboarding·setting presentation 에 이름·구조가
같은 채로 두 벌 있던 UserCancelledAuthException 을 sealed 루트 하나로 모은다.
sealed 로 묶기만 하면 이득이 없어 소비처도 루트로 좁혔다. OnboardingFailureMessage 와
LoginViewModel 의 when 은 subject 가 Throwable 이고 else 를 달고 있어 exhaustiveness
이득이 0 이었다. 루트로 좁혀 사유가 늘면 컴파일러가 두 소비처를 잡게 했고, 기존 else 로
흘려보내던 케이스의 문구는 바꾸지 않았다.
message 는 6종 모두 정적 진단 문구로 통일하고 루트 생성자 파라미터를 non-null 로 좁혔다.
NetworkUnavailable 만 null 이던 것을 맞춘 것으로, 기본 생성에 맡기면 cause.toString() 의
영문 기술 원문이 message 가 되는 것을 막는다는 목적은 그대로다. 규약을 KDoc 이 아니라
타입으로 강제해 하위 타입이 빠뜨릴 수 없게 했다.
UserCancelledAuth 의 기본 메시지 2종("사용자가 로그인을 취소했습니다"/"인증을 취소했습니다")은
소비처가 전부 타입만 보고 갈라내 아무도 읽지 않는 것을 확인하고 하나로 합쳤다. onboarding
쪽에만 있던 존재 이유(코루틴 CancellationException 과 구분)는 루트로 옮겼다.
함께 계정·인증 매퍼 3파일의 주석에서 BE 계약을 복제한 서술(서버 code 의미·엔드포인트·관측
날짜)과 과거 수정 이력을 걷었다. ApiException 이 IOException 을 상속해 when 순서가 곧
의미라는 함정 경고는 남겼다.
This was referenced Aug 24, 2026
Merged
`CoreAuthFailure` 의 `message` 는 리포팅 콘솔용 정적 영문 진단 문구이고, KDoc 도 `e.message ?: 폴백` 을 금지한다. 그런데 LoginEntry 의 소셜 로그인 실패 처리는 `exception.message ?: kakaoFailedMessage` 를 그대로 쓰고 있었다. message 를 non-null 로 좁혀 둔 탓에 `?:` 가 아예 발동하지 않는다 — 폴백 리소스는 영원히 쓰이지 않고, 소셜 로그인이 거절되면 사용자 스낵바에 `social login rejected` 가 그대로 뜬다. 같은 커밋에서 이 경로에 CoreAuthFailure 를 끌어들이면서 바로 아래 줄의 `e.message` 는 남겨 둔 것이 원인이다. 표시 문구는 이미 OnboardingFailureMessage 의 사유별 매핑이 갖고 있으므로 그쪽으로 돌린다. 다만 `UiText.asString()` 은 `@Composable` 이라 코루틴 콜백에서 부를 수 없어, 같은 매핑을 리소스 ID 로 주는 `displayMessageResOrFallback` 을 두고 `context.getString` 으로 푼다 — 매핑을 복제하면 사유가 늘 때 exhaustive when 이 잡아 주지 못한다.
소셜 로그인 실패 문구를 사유별 매핑으로 되돌리면서 `LocalContext.current` 의 `getString` 을 썼는데, Compose lint 가 이를 LocalContextGetResourceValueCall 오류로 막는다(구성 변경 뒤에도 옛 로케일 문자열을 물기 때문). 조회 경로만 `LocalResources.current` 로 바꾼다 — 문구 매핑과 호출 지점은 그대로다. `context` 는 Activity 탐색·CredentialManager 용으로 계속 필요해 남긴다. 검증: :feature:onboarding:presentation:lintDebug --rerun-tasks (오류 0), compileDebugUnitTestKotlin, ktlintMainSourceSetCheck 모두 BUILD SUCCESSFUL.
koongmai
approved these changes
Aug 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#934 의 1·2단계만 담는다. 4-A(수신자)·4-B(애프터노트)는 모듈이 갈려 별도 PR 로 올린다 — 이슈는 닫지 않는다.
무엇을
core:domain에 흩어져 있던 예외 5개와,onboarding·settingpresentation 에 이름·구조가 같은 채로 두 벌 있던UserCancelledAuthException을CoreAuthFailuresealed 루트 하나로 모았다. 파일 7개 → 1개.묶기만 하지 않았다
이슈가 지적한 대로 소비처를 루트로 좁혔다.
OnboardingFailureMessage(5개 중 3개만 분기) 와LoginViewModel(5개 중 2개만 분기) 은when의 subject 가Throwable이고else를 달고 있어 sealed 로 묶어도 exhaustiveness 이득이 0 이었다. 루트로 좁혀 사유가 늘면 컴파일러가 두 소비처를 잡는다.기존
else로 흘려보내던 케이스의 문구는 바꾸지 않았다 — 동작 무변경이다. 폴백이 뜻하는 건 "사유 미확인" 이 아니라 "이 화면에서 줄 전용 문구 없음" 이고, 자격 거절·인증번호 무효·인증 취소 셋은 각각 입력 필드 인라인·무시로 이 함수 밖에서 갈리므로 여기 쓸 문구가 정의된 적이 없다.판단해서 정한 것
message를 6종 모두 정적 진단 문구로 통일하고 루트 생성자 파라미터를String?→String으로 좁혔다.NetworkUnavailable만 null 이라 규칙이 둘이었던 것을 맞춘 것으로, 기본 생성에 맡길 때cause.toString()의 영문 기술 원문이 message 가 되는 것을 막는다는 목적은 그대로다. 규약을 KDoc 이 아니라 타입으로 강제해 하위 타입이 빠뜨릴 수 없게 했다..message를 화면에 싣지 않는다는 규약을 루트 KDoc 에 명시했다..message ?: 폴백프로덕션 소비처 3곳(LoginEntry2,ReceiverMindRecordViewModel1)에 이 예외들이 닿지 않는 것은 실측 확인.UserCancelledAuth의 기본 메시지 2종("사용자가 로그인을 취소했습니다"/"인증을 취소했습니다")은 소비처가 전부 타입만 보고 갈라내 아무도 읽지 않는 것을 확인하고 하나로 합쳤다. onboarding 쪽에만 있던 존재 이유(코루틴CancellationException과 구분해 구조적 동시성을 깨뜨리지 않기 위함)는 루트 KDoc 으로 옮겼다.2026-07-30 실기기 logcat같은 관측 날짜)과 과거 수정 이력을 걷었다.ApiException이IOException을 상속해when순서가 곧 의미라는 함정 경고는 남겼다.검증
:app:compileDebugUnitTestKotlin:app:compileDebugAndroidTestKotlin(#949 신설)ktlintCheck:core:data·:feature:onboarding:presentation·:feature:setting:presentationtestDebugUnitTest시각 검증 해당 없음 — 리소스·디자인 토큰 변경 0. Compose 파일은
ConnectedAccountsScreen.kt하나가 바뀌었으나 import 와if (e !is CoreAuthFailure.UserCancelledAuth)타입 체크 한 줄이라 렌더 결과가 동일하다. baseline 사이클 미실행.리뷰어에게
AfternoteFailureReporting.kt를 4-A PR 도 건드린다. 여기선 백틱 주석 안 심볼명 치환이고, 4-A 는 그 문단을 통째로 지운다. 순차 머지 시 뒤쪽이 리베이스 한 번 필요하고 해결은 "삭제 채택" 이다.ReceiverRequestRejectedException편입은 그 PR 소관, "ApiException→ 도메인 sealed 번역 지점 매퍼 정리" 는 같은 파일을 건드리는 refactor(afternote): data/mapper 명명·배치 정리 — 같은 방향 매핑이 파일 3개·함수명 2종으로 갈림 #932 로 이관 제안.