Skip to content

refactor(core): ReceiverRequestRejectedException 이 서버 원문을 public 접근자로 연다 — 읽는 프로덕션 코드 0건 (#934 분리) #1855

Closed

Description

@OnlyReadOneBook

작업 유형

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

  1. added
    refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업
    area:core공용 코어·네트워크 기능 영역
    on Sep 3, 2026
  2. added
    pr-open이 이슈를 구현하는 PR 이 열려 있다 — base 가 기본 브랜치가 아니어도 드러낸다
    and removed
    pr-open이 이슈를 구현하는 PR 이 열려 있다 — base 가 기본 브랜치가 아니어도 드러낸다
    on Sep 3, 2026
  3. removed
    pr-open이 이슈를 구현하는 PR 이 열려 있다 — base 가 기본 브랜치가 아니어도 드러낸다
    on Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:core공용 코어·네트워크 기능 영역refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions