Skip to content
This repository was archived by the owner on Dec 18, 2025. It is now read-only.
This repository was archived by the owner on Dec 18, 2025. It is now read-only.

[BUG]: safeLocalStorage - 런타임 상태 변경 시 에러 발생 #532

@lucid-jin

Description

@lucid-jin

Package Scope

@toss/storage

Describe the bug

iOS 인앱 브라우저(Google App WebView 등)에서 OAuth 팝업 로그인 플로우 사용 시, safeLocalStorage.get() 호출에서 TypeError: null is not an object (evaluating 'localStorage.getItem') 에러가 발생합니다.

canUse() 체크가 모듈 초기화 시점에만 실행되어, 런타임에 localStorage 상태가 변경되는 경우 MemoStorage fallback이 동작하지 않습니다.

Expected behavior

safeLocalStorage가 런타임에도 안전하게 동작하여, localStorage 접근이 실패하면 MemoStorage로 fallback 되기를 기대합니다.

To Reproduce

  1. iOS 인앱 브라우저 (Google App 등)에서 앱 실행
  2. window.open()으로 OAuth 팝업 창 열기
  3. Google OAuth 페이지로 이동 (cross-origin)
  4. 인증 완료 후 원래 도메인으로 redirect
  5. redirect된 페이지에서 safeLocalStorage.get() 호출
  6. TypeError: null is not an object 에러 발생

재현 환경:

  • iOS 26.x
  • Google App 내장 WebView

Possible Solution

각 메서드에서 런타임 try-catch로 MemoStorage fallback 처리:

class LocalStorage implements Storage {
  private fallback = new MemoStorage();
  
  public get(key: string) {
    try {
      return localStorage.getItem(key);
    } catch {
      return this.fallback.get(key);
    }
  }
  
  public set(key: string, value: string) {
    try {
      localStorage.setItem(key, value);
    } catch {
      this.fallback.set(key, value);
    }
  }
  
  public remove(key: string) {
    try {
      localStorage.removeItem(key);
    } catch {
      this.fallback.remove(key);
    }
  }
}

기존 MemoStorage fallback 철학을 유지하면서, 런타임에도 안전하게 동작할 수 있습니다.

Additional context

  • 현재 canUse()는 모듈 로드 시 1회만 실행됨
  • 초기화 시점에는 localStorage가 정상이었으나, cross-origin 이동 후 null로 변경되는 케이스
  • Safari Private Mode (처음부터 불가)와 달리, 런타임에 상태가 변하는 케이스임

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions