Repository navigation
refactor(core): ReceiverRequestRejectedException 이 서버 원문을 public 접근자로 연다 — 읽는 프로덕션 코드 0건 (#934 분리) #1855
Description
작업 유형
refactor — 동작 변경 없는 구조·책임·경계 개선
주 담당 모듈
core — 코어
개요
기준: origin/develop e400b07a6.
core:domain 의 ReceiverRequestRejectedException 이 서버 응답 원문을 userMessage 라는 public 접근자로 열어 둔다.
class ReceiverRequestRejectedException(
val userMessage: String,
cause: Throwable,
) : Exception(userMessage, cause)1. 읽는 프로덕션 코드가 0건이다
e400b07a6 전수 스캔 결과 .userMessage 를 읽는 곳은 테스트 1곳뿐이다.
| 위치 | 소스셋 | 형태 |
|---|---|---|
core/data/src/test/java/com/afternote/core/data/repoimpl/ReceiverRequestFailureTest.kt:70 |
test | assertEquals("수신자 이메일은 필수입니다.", domainError.userMessage) |
feature/setting/presentation/.../viewmodel/ReceiverFailureMessage.kt:9 |
main | KDoc 링크뿐 — 코드가 아니다 |
유일한 소비처인 ReceiverFailureMessage.kt:16 은 타입만 보고 로컬 리소스를 고른다. 값은 쓰지 않는다.
if (this is ReceiverRequestRejectedException) {
UiText.Resource(R.string.receiver_request_rejected)
} else {
UiText.Resource(fallbackResId)
}2. 이름이 저장소 규약의 반대를 광고한다
CoreAuthFailure·ReceiverFailure 두 sealed 루트의 KDoc 은 «서버 message 는 사용자 노출용이라는 규정이 없다(BE#92)» 를 근거로 서버 문구를 화면에 싣지 않는다고 못박는다. ReceiverFailureMessage.kt 도 그 경고에 KDoc 3줄을 쓴다.
그런데 userMessage 는 core:domain 의 public 접근자라 어느 feature 모듈에서든 읽어 그대로 화면에 실을 수 있다. 이름 자체가 "사용자에게 보여 줄 문구"로 읽혀 그 오용을 부른다. 규약이 주석으로만 지켜지고 있다.
3. KDoc 이 댄 존치 근거가 사실과 다르다
ReceiverFailureMessage.kt:9-11 은 이 값을 «리포팅·로그 용도로만 예외에 남긴다» 고 설명한다. 그런데 ErrorReporter.recordFailure 는 리포팅 백엔드로 보내기 전에 redact(throwable) 를 통과시킨다.
private fun redact(throwable: Throwable): Throwable =
RedactedFailure(throwable.javaClass.name).apply {
stackTrace = throwable.stackTrace
}RedactedFailure 는 message 를 타입 이름으로 갈아치우고 cause 도 잇지 않는다. 서버 문구는 리포팅 백엔드에 닿지 않는다 — 존치 근거가 성립하지 않는다.
완료 조건
ReceiverRequestRejectedException에서 public 접근자val을 뗀다. 생성자 파라미터는 남기고 이름을serverMessage로 바꿔 «서버 원문» 이라는 실체를 이름이 말하게 한다.- 생성자 시그니처(인자 개수·순서·타입)는 바꾸지 않는다 — 아래 범위 밖 참고.
ReceiverRequestFailureTest.kt:70의 단언을message로 옮긴다. 서버 문구가Exception.message로 계속 전달된다는 사실은 그대로 검증한다.ReceiverFailureMessage.kt의 KDoc 에서 사라진 접근자 링크를 걷고, 존치 근거가 아니라 실제 규약(타입만 보고 로컬 리소스를 고른다)을 적는다. KDoc 링크는 CI 게이트 밖이라 수동으로 맞춘다.core:domain·core:data·feature:setting:presentation컴파일·단위 테스트·ktlintCheck·:konsist:test통과.
자식 이슈
No response
참고
#934 에서 분리했다. 본 이슈는 #934 의 재감사(2026-09-03)에서 «지금 열린 PR 과 충돌 없이 닫을 수 있는 몫» 으로 갈라낸 것이고, #934 는 총괄로 열려 있다.
범위 밖 — 생성자 시그니처 변경은 여기서 하지 않는다. 서버 문구를 Exception.message 에서까지 걷어 정적 진단 문구로 바꾸는 일은 유일한 생산 지점 core/data/.../UserRepositoryImpl.kt:293 의 mapReceiverRequestFailure 를 고쳐야 하는데, #1595 가 그 함수를 통째로 UserReceiverRepositoryImpl.kt 로 옮긴다(APPROVED·MERGEABLE). 지금 그 줄을 건드리면 정면 충돌한다. #1595 머지 뒤 #934 에서 이어 간다.
이 이슈가 건드리는 3파일(ReceiverRequestRejectedException.kt · ReceiverRequestFailureTest.kt · ReceiverFailureMessage.kt)은 2026-09-03 기준 열린 PR 66건 중 어느 것도 건드리지 않는다(전수 대조).
#1672(테스트만 접근하는 core 선언 private 축소)와는 대상이 겹치지 않는다 — 그쪽 확정 목록 21개는 core:data·core:ui·core:network·core:common·core:datastore 이고 core:domain 의 error 패키지는 없다.
Activity