fix: 스토리지 차단 환경에서 랜딩 리다이렉트 크래시 방어#283
Merged
Merged
Conversation
* feat: 어드민에 Flyway 버전 형상 뷰어 추가
- /flyway 라우트 + 사이드바 메뉴
- flyway API/쿼리 모듈 (overview/script/wip)
- FlywayViewer: 4단계 파이프라인, 같은번호 충돌·순서역전 배너, 검색/상태필터,
마스터-디테일(CodeMirror SQL), 다음 안전 번호
- WipRegisterForm: 작업중 등록(새/기존 테이블, 기존 테이블 검색) → 백엔드 이슈 생성
* feat: Flyway 뷰어 UI 개선 — 순서역전 행 표시 / dev·prod 파이프라인 레이블
- STATUS_META: MERGE_PENDING→'dev 반영', DB_APPLIED→'prod 반영'
- 순서역전 행: 좌측 컬러 세로선(컬럼=빨강, 테이블=주황) + 인라인 배지
('⚠ 컬럼 역전' / '🔀 순서 역전')
- 상단 배너 severity 표기: TABLE→'테이블', COLUMN→'컬럼'으로 한글화
- SQL 패널: 선택 마이그레이션이 순서역전 대상이면 경고 블록 표시
(공유 테이블/컬럼명 하이라이트, 강약 구분 색상)
* chore: 연속 읽기 보호막 API 타입 반영 (cherry picked from commit 338cdcc) * design: 연속 읽기 보호막 사용 완료 아이콘 추가 (cherry picked from commit 3997771) * feat: 연속 읽기 보호막 정보 컴포넌트 추가 (cherry picked from commit 119f0fd) * feat: 연속 독서왕 내 순위 보호막 표시 추가 (cherry picked from commit 2f80a09) * chore: 연속 읽기 보호막 목 데이터 추가 (cherry picked from commit 834124c) * chore: 연속 읽기 보호막 API 타입 정리 (cherry picked from commit 711b1fb) * fix: 체리픽 생성 타입 정합성 수정
localStorage 접근이 SecurityError로 throw하는 환경(스토리지 차단 인앱/크롤러)에서 _bombom beforeLoad가 실패해 라우트 기본 에러 UI가 노출되던 문제 수정. createStorage를 try/catch로 감싸 실패 시 기본값 반환·noop 처리하고, 라우터에 defaultErrorComponent 안전망 추가.
jaeyoung-kwon
commented
Jul 1, 2026
jaeyoung-kwon
left a comment
Contributor
Author
There was a problem hiding this comment.
🤖 PR Review
✅ 확실하게 수정이 필요한 항목을 찾지 못했습니다.
localStorage 접근이 SecurityError로 throw하는 환경에서 라우트 crash를 방지하는 방어적 수정입니다. createStorage의 get/set/remove를 모두 try/catch로 감싸고 모듈 최상단 window.localStorage 참조를 지연시켰으며, 랜딩 방문 플래그를 안전 래퍼로 통일했습니다. 기존 raw 문자열 'true'로 저장된 값도 JSON.parse('true') === true로 정상 호환되고, PageErrorFallback은 이미 SentryErrorBoundary fallback으로 쓰이던 컴포넌트를 재사용해 router defaultErrorComponent에 안전하게 연결됩니다. 회귀 테스트 3건도 각 케이스(get/set/remove throw)를 적절히 커버하고 afterEach에서 mock을 정상 복원합니다. introduced diff 범위 내에서 production 이슈, 보안, 데이터 손상, 사용자 플로우 차단 리스크를 발견하지 못했습니다.
🚨 0 Critical ·
📋 검증 과정
- Claude structured review 결과 중 확신도가 있는 항목만 정리했습니다.
- Critical/Major는 inline comment로 게시하고, Minor는 참고 항목으로 summary에 포함합니다.
- 자동 생성된 OpenAPI 타입 선언 파일과 lock 파일은 리뷰 대상에서 제외합니다.
🤖 Claude PR Review
Generated by Claude Code
JeLee-river
approved these changes
Jul 7, 2026
JeLee-river
left a comment
Contributor
There was a problem hiding this comment.
이런 이슈가 있었나보네요.. 작업해주셔서 감사합니다~!
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.
📌 What
스토리지 접근이 막힌 환경(시크릿·인앱 브라우저·일부 링크 미리보기 크롤러)에서
www.bombom.news진입 시_bombom라우트가 크래시하며 TanStack Router 기본 에러 UI(Something went wrong! Show Error.)가 노출되던 문제를 수정합니다.❓ Why
/진입은/_bombom/_main/에 매칭돼_bombom.beforeLoad가 반드시 실행됩니다. 여기서localStorage.getItem(LANDING_VISITED_KEY)를 무방비로 호출하는데, 스토리지가 차단된 컨텍스트에서는window.localStorage접근 자체가SecurityError를 던집니다.beforeLoad가 reject → 해당 라우트의 기본errorComponent가 본문을 덮음SentryErrorBoundary까지 올라오지 않고, 라우터에 Sentry 캡처 훅도 없어 Sentry에도 잡히지 않은 채 조용히 노출됨추가로
utils/localStorage.ts는 모듈 최상단에서const storage = window.localStorage를 잡고 있어, 이 유틸을 쓰는 lazy 청크들도 스토리지 차단 시 import 단계에서 터질 수 있는 잠재 크래시가 있었습니다.🔧 How
createStorage의get/set/remove를 각각 try/catch로 감싸고, 모듈 최상단window.localStorage참조를 제거해 접근을 지연시킴. 실패 시get은defaultData반환,set/remove는 noop.landingVisitedStorage = createStorage<boolean>(KEY, false))로 통일해_bombom.beforeLoad·landing.tsx의 rawlocalStorage호출을 제거. 스토리지 차단 시에는false→ 기존 의미대로/landing리다이렉트로 폴백.'true')은 JSON 파싱과 호환되어 재방문자 플래그가 유지됩니다.defaultErrorComponent: PageErrorFallback를 추가해, 앞으로 어떤 라우트가 죽어도 영문 기본 UI 대신 한국어 폴백이 뜨도록 안전망 추가.검증
localStorage접근이 throw하도록 주입 →/가Something went wrong! Show Error.렌더됨을 재현(원인 확정)createStorage.get()이SecurityError에서false반환 →/landing리다이렉트로 이어짐을 유닛 테스트로 검증tsc --noEmit/ eslint / jest 전부 통과👀 Review Point
utils/localStorage.ts안전화 (throw 시 기본값/noop, 최상단 참조 제거)_bombom.beforeLoad,landing.tsx)defaultErrorComponent안전망🤖 Generated with Claude Code