Skip to content

공통 오류 안내의 상황별 문구·액션·적용 범위를 PM에게 확인한다 #446

Closed as not planned
2 of 2 issues completed
Closed as not planned

Description

@OnlyReadOneBook

작업 유형

refactor — 동작 변경 없는 구조·책임·경계 개선

주 담당 모듈

core — 코어

개요

과거 2026-08-23 포괄 위임으로 401/404/4xx 문구와 액션을 FE가 확정했다는 본문을 철회한다. 시안 추가 기록과 이후 FE 확정안이 서로 달라, 옛 댓글의 '게이트 해제'도 착수 승인으로 사용하지 않는다. #1736/PR #1609로 분리된 기존 범위를 다시 구현하지 않는다.

PM 확인이 필요한 결정

401 재로그인, 404 항목 부재, 4xx 입력·거절, 단말 파일 저장 실패별 문구·버튼·닫기·재시도·복귀와 화면별 모달/인라인/스낵바 적용 범위를 PM에게 확인한다. 서버 메시지 원문 노출을 기본값으로 정하지 않는다. 확정된 오류 계약을 유지하는 내부 매핑·결함 수정은 별도 판단한다. 타인 담당 #1542/#1543은 이 이슈의 과거 FE 결정만으로 착수할 수 없다.

완료 기준

PM의 명시적인 답변과 적용 범위·근거 링크를 기록한다. 답변 전에는 구현·재개·테스트 완료 체크리스트를 예약하지 않는다. 결정 후 최신 코드와 계약을 대조해 실제 필요한 작업만 정의한다. 디자이너에게 질문하거나 태그하지 않으며, 미답변이나 과거 FE 재량 위임을 승인으로 해석하지 않는다.

정리 근거

2026-09-13 사용자 요청에 따라 미확정 구현 예약을 제거했다. 기능 구현 완료를 의미하지 않는다. 기존 댓글의 실측은 참고 자료이며, 상충하는 옛 구현 지시는 현재 범위를 대체하지 않는다.

Activity

  1. OnlyReadOneBook commented on Aug 8, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    게이트 해소 — 2026-08-08 질의한 미커버 3종 팝업이 시안에 추가됐습니다.

    2026-08-09 새벽 류하늬 님 회신("추가했습니다") + 버전 diff 실측, 공통 에러 팝업 섹션 확장. 실측 문구:

    1. 재입력으로 풀리는 거절 — "입력 정보를 확인해 주세요." / "입력한 정보가 올바르지 않거나 유효 시간이 만료되었습니다. 다시 확인해 주세요." / [다시 입력하기]
    2. 삭제된 항목 — "삭제된 애프터노트입니다." / "이미 삭제되었거나 더 이상 확인할 수 없는 애프터노트입니다." / [목록으로 돌아가기]
    3. 로그인 만료 — "로그인이 만료되었어요." / "계속 이용하려면 다시 로그인해 주세요." / [재로그인하기]

    기존 4종(네트워크/서버 오류/업로드 실패/접근 권한 없음)과 합쳐 실패 상황 커버가 확정됐고, 표시 방식 통일에 착수할 수 있습니다. blocked: 디자인 라벨도 제거했습니다.

  2. changed the title [-]refactor(core): 작업 실패 안내 표시 방식 통일 — 인라인 문구·스낵바 혼재 해소[/-] [+]작업 실패 안내 표시 방식 통일 — 인라인 문구·스낵바 혼재 해소[/+] on Aug 28, 2026
  3. added
    refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업
    area:core공용 코어·네트워크 기능 영역
    and removed
    enhancementNew feature or request
    on Aug 28, 2026
  4. OnlyReadOneBook commented on Aug 28, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    현황 표가 인라인·스낵바만 조사해 Toast 사용처 2건이 누락돼 있습니다 — 수신자 내려받기 실패(ReceiverHomeScreen.kt:173, #652 에서 문구만 교정)와 모든 기록 내려받기 실패(ReceiverAfternoteScreen.kt:66). 둘 다 서버 작업 실패라 이 이슈의 확정 체계(공통 에러 팝업) 정렬 대상입니다. 추적은 #1391 에 등재했습니다.

  5. OnlyReadOneBook commented on Aug 28, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    현황 표 누락분 보강 — 수신자 내려받기 실패 2건 (Toast → 잠정 Snackbar)

    본문 현황 표는 인라인 문구·스낵바만 조사해서 android.widget.Toast 사용처가 빠져 있었다. #1391 에서 레포 전수 실측한 결과 Toast 실사용 3건이 전부 receiver 모듈이었고, 그중 서버 작업 실패 2건이 이 이슈의 정렬 범위다. 나머지 1건(영상 재생 앱 없음)은 서버 실패가 아닌 로컬 환경 안내라 팝업 4종 어디에도 안 들어가므로 이 이슈 범위 밖이며 #1391 이 계속 추적한다.

    PR #1412 에서 두 건을 잠정 Snackbar 로 전환했다(#713 전례 — Toast 는 앱 테마·시안을 안 타고 Compose semantics 에 안 잡혀 어떤 테스트로도 단언할 수 없어 먼저 걷었다). 공통 에러 팝업 컴포넌트가 나오면 이 두 곳도 재정렬 대상이며, 그 재정렬은 이 이슈가 추적한다.

    화면 실패 종류 #1412 이전 #1412 이후 확정안 정렬 시
    수신자 홈(ReceiverHomeScreen · DownloadDialogHost) 모든 기록 내려받기 실패 / 파일 저장 실패 Toast 스낵바(잠정) 모달 팝업 — 내려받기 실패는 네트워크·서버 오류로 매핑되나 파일 저장 실패는 4종 매핑이 자명하지 않다(아래)
    수신자 애프터노트 요약(ReceiverAfterNoteEntry) 모든 기록 내려받기 실패 Toast 스낵바(잠정) 모달 팝업

    두 곳 모두 코드에 "정본은 #446 공통 에러 팝업이라 컴포넌트가 나오면 재정렬된다"는 주석을 달아 뒀다. 전환은 실패 문구를 바꾸지 않았고(기존 string resource 그대로), 표출은 Robolectric Compose 테스트 3건으로 가드된다 — 정렬 작업 때 회귀 확인용으로 그대로 쓸 수 있다.

    본문 「남은 확정 사항 — 실패 종류 매핑」에 1건 추가한다. 「파일 저장 실패」(receiver_home_download_all_save_failed)는 서버 응답은 성공했는데 단말 저장에서 실패한 경우다. 「업로드 실패」의 반대 방향이고 「서버 오류」도 아니라 4종 중 어디로 보내도 오분류이며, 재시도 자체는 의미가 있으나 원인 문구가 없다 — 본문 🔴 디자이너 몫 3건(4xx 거절 사유 · 404 · 401)과 같은 갈래로 함께 물어볼 후보다.

  6. 9 remaining items

  7. OnlyReadOneBook commented on Sep 2, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    core:ui 팝업 3종 + receiver 열람 신청 2화면 정렬 + 재시도 실제 재요청을 #1736 로 분리했고 PR #1609 가 그 이슈를 Closes 합니다. 수신자 홈 내려받기 실패 2건은 home 담당 이슈 #1737 로 세웠습니다(#1736 에 blocked).

    이 이슈에 남는 몫: 401·404·4xx 변형 3종(시안 3970:* 기준으로 문구 재확정 — 본문 FE 확정안은 낡음), 예외→범주 매핑 core 수렴, MasterKeyScreen(#1579 머지돼 착수 가능), afternote DetailLoadErrorContent(#705 조정), 403 생산자 배선.

    자식 #1542·#1543 의 blocked_by 는 이 이슈에 그대로 둡니다 — 그들 선행에 401/404/4xx 변형이 포함돼 3종만으로는 못 풉니다.

  8. removed
    pr-open이 이슈를 구현하는 PR 이 열려 있다 — base 가 기본 브랜치가 아니어도 드러낸다
    on Sep 2, 2026
  9. changed the title [-]refactor(core): 작업 실패 안내를 공통 오류 팝업으로 통일 — core:ui 팝업 3종 추가 + afternote·receiver 정렬[/-] [+]공통 오류 안내의 상황별 문구·액션·적용 범위를 PM에게 확인한다[/+] on Sep 12, 2026
  10. OnlyReadOneBook commented on Sep 13, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    PM 전건호에게 Figma 댓글로 질문했다(2026-09-13). 이 이슈는 그동안 PM 확인 대기로 분류돼 있었지만 실측해 보니 어느 채널에도 발신 기록이 없었다. 이번이 첫 발신이다.

    물은 것은 묵은 본문의 질문을 그대로 옮긴 것이 아니라 origin/develop 86ab223 실코드와 현재 시안으로 다시 벼린 것이다.

    본문에 있었지만 이번 질문에서 뺀 축:

    (1) 401·404·4xx 문구와 버튼을 무엇으로 할지 묻는 축을 통째로 뺐다. 정본 페이지 4327:72071 에 7종 전부 문구와 버튼 라벨까지 확정돼 있어 FE 가 그대로 쓰면 된다. 본문의 2026-08-29 FE 확정안(요청을 처리하지 못했습니다 / 찾을 수 없습니다 / 다시 로그인해 주세요)은 시안과 달라 인용하지 않았다. (2) «서버 메시지 원문 노출을 기본값으로 할지» 축을 뺐다. ReceiverRequestRejectedException 이 BE#92 를 근거로 원문 접근자를 막아 뒀고 BaseResponse KDoc 이 500 응답에 내부 SQL 이 실린 실측(#511)을 남겨 이미 닫힌 결정이다. 대신 사유가 다섯인데 팝업이 하나라는 진짜 미결 지점을 1번으로 물었다. (3) 본문이 근거로 든 시안 링크 3628:23827 을 앵커로 쓰지 않았다. Figma MCP 로 확인하니 그 노드는 back up 페이지(34:116) 소속이고, 정본 페이지의 같은 크기(2668×433) 대응물이 4327:72071 이다. 2026-08-08 코멘트가 걸어 둔 3628:23575 도 back up 페이지다. 2026-09-02 코멘트가 말한 시안 3970:* 는 해석되지 않았다. (4) 본문의 ReceiverMasterKeyException·ReceiverEmailAuthException 은 86ab223 에 존재하지 않아 빼고 현행 ReceiverRejectionReason 5종으로 대체했다. (5) #1736/PR #1609 로 분리돼 이미 구현된 core:ui 팝업 3종과 receiver 열람 신청 2화면 정렬은 질문에서 뺐다.

  11. OnlyReadOneBook commented on Sep 13, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    착수 전 실측 기록 (2026-09-13, origin/develop 7d87aa3)

    이 이슈로 지금 낼 코드는 0줄이다. 완료 기준 네 항목 중 둘("PM의 명시적인 답변...을 기록한다", "결정 후 최신 코드와 계약을 대조해...")은 PM 답변이 산출물이라 막혀 있고, 나머지 둘은 금지 조항이라 산출물이 없다. 열린 PR 62건의 변경 파일을 전수로 훑어 core/ui/.../popup/, core/ui strings.xml, receiver data/error/·presentation/error/, 홈 내려받기 팝업 호스트, PhotoUploadRepositoryImpl.kt 를 건드리는 PR 은 0건이고, 이 이슈를 Closes 하는 열린 PR 도 없다(#1365 가 본문에서 후속 과제로 언급할 뿐이다).

    대신 이 이슈가 풀리는 시점에 읽혀야 할 실측 네 가지를 남긴다. #1542·#1543 이 이 이슈를 blocked_by 로 물고 있어서, 해제되는 순간 담당자가 그 본문의 매핑표부터 읽는다. 그 표에 아래 내용이 없다.

    1. 크기 초과 갈래가 develop 의 팝업 체계에 없다

    core/ui/src/main/kotlin/com/afternote/core/ui/popup/ErrorPopup.kt 에 선 팝업은 NetworkErrorPopup(64행)·ServerErrorPopup(86행)·UploadErrorPopup(108행) 3종이고, 셋 다 파라미터가 onRetry·onDismiss 둘이라 유일한 액션이 재시도다. 버튼 문자열도 core/ui/src/main/res/values/strings.xml 40·43·46행이 전부 "다시 시도하기"다.

    서버 계약 쪽은 확정돼 있다. Afternote-BE src/main/java/com/afternote/global/exception/ErrorCode.java:186 이 FILE_SIZE_EXCEEDED(HttpStatus.BAD_REQUEST, 1803, "업로드 파일 크기가 허용 한도를 초과했습니다.") 이고, 경계는 10,485,760 B(10 MiB)로 실기기 이진 탐색까지 끝나 있다(docs/qa/device-baseline.md:173, 근거 docs/qa/evidence/a23e50fa3040a1025811f79cffd26c2e47b11323.json).

    FE 메인·테스트 소스에서 1803 을 다루는 코드는 0건이다. 문자열 1803 이 걸리는 자리는 konsist 의 이슈 번호 주석 4건(그쪽은 이슈 #1803 이고 이 오류 코드와 무관하다)과 위 QA 근거 JSON 뿐이다.

    2. 자식 두 이슈의 매핑표가 크기 초과를 재시도 버튼으로 보낸다

    #1542·#1543 본문의 "예외 → 범주 매핑 (#446 확정)" 중 "파일 업로드 경로 실패 → 업로드 실패" 한 줄이 그 경로다. 두 모듈이 같은 업로드 경로를 탄다는 근거는 이렇다.

    core/data/src/main/java/com/afternote/core/data/repoimpl/PhotoUploadRepositoryImpl.kt:100 이 상한 검사도 압축도 없이 contentLength = tempFile.length() 를 그대로 실어 보낸다. mindrecord 는 DailyQuestionWriteViewModel.kt:250·DiaryWriteViewModel.kt:158 이 그 실패를 mindrecord_error_image_upload_failed(strings.xml:221, "이미지를 올리지 못했어요. 다시 시도해 주세요.") 하나로 받고, timeletter 는 ResolveTimeLetterBlocksUseCase.kt:36-39 가 같은 photoUploadRepository.upload 를 getOrElse { throw it } 로 흘린다. 같은 UseCase 의 validateLocalMedia(67-78행)는 MIME 만 검사하고 크기는 보지 않는다.

    지금은 누를 수 없는 안내 문구인 것이 팝업 정렬 뒤에는 누를 수 있는 재시도 버튼이 된다. 결함이 이월되는 정도가 아니라 강해진다.

    3. 이미 머지된 두 소비처가 그 구멍을 각각 다르게 비켜 갔다

    둘 다 이 이슈가 확정할 계약의 선례다.

    receiver: feature/receiver/data/.../error/ReceiverFailureTranslation.kt:79-81 이 4xx + 비어 있지 않은 serverMessage 를 UserRejection(reason = null) 로 접고, feature/receiver/presentation/.../error/ReceiverErrorPopup.kt:48 의 toReceiverErrorPopupOrNull 이 UserRejection 에 null 을 돌려줘 팝업이 아니라 스낵바로 보낸다. 같은 파일 KDoc 32-34행이 이유를 "다시 시도하기 버튼을 주면 같은 입력으로 같은 거절을 반복하게 만든다"로 적어 뒀다. 1803 은 400 에 위 한국어 문구를 실어 오므로 이 게이트의 reason = null 갈래에 떨어져 재시도 버튼이 붙지 않는다.

    home: feature/home/presentation/.../receiver/ReceiverHomeDownloadErrorPopupHost.kt:36-45 가 시안 4종에 대응 항목이 없는 "파일 저장 실패"를 AfternoteErrorPopup 골격에 화면 자기 문구를 실어 그렸다(#1737, CLOSED). 4종 밖 갈래를 시안 밖 새 모양 없이 처리한 선례다.

    4. 물은 적 없는 축의 답을 두 이슈가 기다리고 있다

    오늘 세운 #2080·#2081 의 완료 조건 마지막 줄이 "표시할 문구는 #446 이 PM 답변으로 확정한 값을 쓴다"인데, 오늘 발신한 질문의 구성과 뺀 축 다섯 어디에도 크기 초과 축이 없다. 후속 질문에 그 축을 넣든 #2080·#2081 의 기대를 조정하든 한쪽을 정해야 한다.

    본문·자식 본문이 develop 실태와 어긋나는 항목

    본문은 고치지 않았다. 아래는 전부 완료 기준을 넓히거나 좁히는 편집이 아니라 사실 정정이라 기록으로만 남긴다.

    1. 본문이 PM 확인 대상으로 든 "단말 파일 저장 실패" 문구는 이미 develop 에 실려 머지돼 있다. 위 3번의 홈 팝업 호스트가 home_receiver_download_save_error_title("저장 실패", feature/home/presentation/.../strings.xml:40)·_description(42행)을 쓴다(refactor(home): 수신자 홈 내려받기 실패 2건을 공통 오류 팝업으로 옮긴다 (#446 분리) #1737). 아직 정할 문구가 아니라 이미 정해진 문구의 사후 승인 문제다.
    2. 본문의 401·404·4xx 문구·버튼 질문 축과 "서버 메시지 원문 노출" 축은 실제 발신분에서 빠졌다. 사유는 바로 앞 코멘트에 적어 뒀고, 본문은 그대로다.
    3. refactor(mindrecord): 작성 화면 2곳의 실패 안내를 인라인 문구에서 공통 오류 팝업으로 (#446 분할) #1542·refactor(timeletter): 작성 화면 실패 안내 스낵바 5곳을 공통 오류 팝업으로 (#446 분할) #1543 본문의 "확정된 표시 방식" 4종 표는 develop 과 다르다. "접근 권한 없음" 팝업은 없다. ErrorPopup.kt 에는 Network·Server·Upload 3종뿐이고 31-32행 KDoc 이 "접근 권한 없음(403)은 아직 생산자가 없어 세우지 않았다"고 적어 뒀다. 4종이 다 서 있다는 전제로 착수하면 틀린다.
    4. refactor(mindrecord): 작성 화면 2곳의 실패 안내를 인라인 문구에서 공통 오류 팝업으로 (#446 분할) #1542·refactor(timeletter): 작성 화면 실패 안내 스낵바 5곳을 공통 오류 팝업으로 (#446 분할) #1543 본문이 인용한 매핑표 중 4xx·404·401 세 줄은 이 이슈 본문이 오늘 철회한 FE 확정안이고, 앞 코멘트가 정본 시안과 문구가 달라 인용하지 않겠다고 적은 값이다. 두 자식 본문에는 철회가 반영돼 있지 않다.
  12. OnlyReadOneBook commented on Sep 18, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    PM 결정 대기 항목은 깃허브 이슈로 두지 않고 피그마 질문 한 자리에만 둔다(2026-09-18 결정). 이 이슈의 질문은 피그마 스레드에 걸려 있다: https://www.figma.com/design/UP9ZR186jHvRBicjA2SOea/?node-id=4327-72071#1923877288 답이 오면 그 답을 근거로 구현 이슈를 새로 만든다.

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

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions