Skip to content

Conversation

@jllee000
Copy link
Collaborator

@jllee000 jllee000 commented Dec 22, 2025

📌 Related Issues

관련된 Issue를 태그해주세요. (e.g. - close #25)

📄 Tasks

  1. 기존 온보딩 로그인 시에, 로컬스토리지로만 토큰 저장 -> 크롬 스토리지 저장 로직 추가
  2. instance 추가 설정
  3. 크롬 객체 추가 설치

⭐ PR Point (To Reviewer)

TypeError 방지 환경 조건 문 추가

 if (typeof chrome !== 'undefined' && chrome.storage?.local) {
          chrome.storage.local.set({ token: newToken }, () => {
            console.log('Token saved to chrome storage');
          });
        }

📷 Screenshot

Summary by CodeRabbit

  • 새로운 기능

    • 로그인·회원가입 시 인증 토큰을 Chrome 확장 로컬 저장소에 병기 저장하도록 추가되었습니다.
  • 개선사항

    • 인증 흐름을 간소화하고, 인증 실패(401/403) 시 토큰 정리 후 온보딩(소셜 로그인)으로 리디렉션하도록 동작을 명확히 했습니다.
    • Chrome 확장 호환성 및 안정성 향상.
  • 잡무(Chore)

    • 개발용 Chrome 타입 정의(@types/chrome) 추가.

✏️ Tip: You can customize this high-level summary in your review settings.

@jllee000 jllee000 self-assigned this Dec 22, 2025
@vercel
Copy link

vercel bot commented Dec 22, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
pinback-client-client Ready Ready Preview, Comment Dec 22, 2025 3:12am
pinback-client-landing Ready Ready Preview, Comment Dec 22, 2025 3:12am

@coderabbitai
Copy link

coderabbitai bot commented Dec 22, 2025

Walkthrough

클라이언트와 익스텐션의 인증 흐름을 단순화하고, 로그인/회원가입 콜백에서 토큰을 브라우저 확장 저장소(chrome.storage.local)에 추가로 저장하도록 변경했습니다. 또한 클라이언트·익스텐션의 axios 인터셉터에서 토큰 재발급 로직을 제거하고 리다이렉트 흐름을 간소화했습니다.

Changes

Cohort / File(s) 변경 요약
패키지 의존성
apps/client/package.json
개발 의존성으로 @types/chrome (^0.0.273) 추가
클라이언트 — 온보딩/회원가입 토큰 동기화
apps/client/src/pages/onBoarding/GoogleCallback.tsx, apps/client/src/shared/apis/queries.ts
구글 콜백 및 회원가입 성공 시 기존 localStorage에 더해 chrome.storage.local.set으로 토큰을 저장하도록 추가 (로깅 콜백 포함)
클라이언트 — axios 인터셉터 단순화
apps/client/src/shared/apis/setting/axiosInstance.ts
내부 토큰 재발급(fetch/refresh) 및 관련 조건 로직 제거. 요청 인터셉터는 localStorage에서 토큰을 읽어 Bearer로 붙이고, 응답 401/403 시 토큰 삭제 후 온보딩으로 리다이렉트하도록 간소화
익스텐션 — axios 인터셉터 및 온보딩 리다이렉트 변경
apps/extension/src/apis/axiosInstance.ts
토큰 취득을 스토리지 기반(getTokenFromStorage)으로 변경, 요청 인터셉터 단순화, 401/403 처리 시 온보딩으로 리다이렉트(리다이렉트 가드 및 환경별 온보딩 URL 포함) 및 저장 토큰/이메일 정리 로직 추가

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • 집중 검토 권장 파일:
    • apps/client/src/shared/apis/setting/axiosInstance.ts (토큰 재발급 제거에 따른 경로/에러 처리 변경)
    • apps/extension/src/apis/axiosInstance.ts (리다이렉트 가드, 환경별 URL, 스토리지 정리)
    • apps/client/src/pages/onBoarding/GoogleCallback.tsxapps/client/src/shared/apis/queries.ts (chrome.storage 사용 시 콜백·권한/타이핑 점검)

Possibly related PRs

Suggested labels

⚙️ Setting

Suggested reviewers

  • constantly-dev
  • jjangminii

Poem

🐰 옆집 토끼가 말하네, 토큰 한 알 쏙 넣어두었네.
local엔 기본, chrome엔 보너스,
로그인 길이 반짝이며 이어지고,
리다이렉트는 깔끔히 정리했네.
토끼가 지켜줄게 — 안전한 동기화! 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 온보딩 토큰 저장 로직 수정에 관한 변경사항을 명확히 설명하며, 실제 코드 변경과 일치합니다.
Description check ✅ Passed PR 설명이 관련 이슈 #223을 명시하고, 작업 내용과 리뷰어를 위한 주요 포인트를 포함하고 있습니다.
Linked Issues check ✅ Passed 이 PR은 이슈 #223의 요구사항(로그인 토큰을 localStorage와 Chrome 저장소에 모두 저장, 타입 안전성 보장)을 충족합니다. 이슈 #25는 이 PR과 무관합니다.
Out of Scope Changes check ✅ Passed 주요 변경사항들(토큰 저장 로직, axiosInstance 수정, Chrome 타입 정의 추가)은 모두 이슈 #223의 범위 내입니다. 토큰 갱신 로직 제거도 기존 온보딩 로직을 단순화하는 관련 변경입니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#223/onboarding-token-save

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 22, 2025

✅ Storybook chromatic 배포 확인:
🐿️ storybook

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
apps/client/src/pages/onBoarding/GoogleCallback.tsx (1)

30-34: Chrome storage 저장 완료 전에 페이지 이동이 발생합니다.

토큰이 Chrome storage에 저장되기 전에 navigate('/')가 실행될 수 있습니다. 온보딩 과정에서의 초기 토큰 설정이므로, 이 시점에서 저장이 완료되지 않으면 이후 페이지에서 Chrome storage의 토큰을 사용할 수 없을 수 있습니다.

이는 axiosInstance.ts의 lines 24-28에서 플래그한 것과 동일한 패턴입니다.

🔎 비동기 저장 완료 후 이동하도록 수정 제안
       if (accessToken) {
         localStorage.setItem('token', accessToken);
 
         if (typeof chrome !== 'undefined' && chrome.storage?.local) {
-          chrome.storage.local.set({ token: accessToken }, () => {
-            console.log('Token saved to chrome storage');
-          });
+          try {
+            await chrome.storage.local.set({ token: accessToken });
+            console.log('Token saved to chrome storage');
+          } catch (error) {
+            console.error('Chrome storage 저장 실패:', error);
+          }
         }
       }
apps/client/src/shared/apis/queries.ts (1)

83-87: Chrome storage 저장이 완료되기 전에 다음 작업이 실행됩니다.

chrome.storage.local.set이 완료되기 전에 sendTokenToExtension이 호출됩니다. 이는 axiosInstance.ts lines 24-28에서 플래그한 것과 동일한 race condition 패턴입니다.

중앙화된 토큰 저장 유틸리티 함수를 만들어 세 곳 모두에서 일관되게 사용하는 것을 권장합니다.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11b299e and bb5130a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • apps/client/package.json
  • apps/client/src/pages/onBoarding/GoogleCallback.tsx
  • apps/client/src/shared/apis/queries.ts
  • apps/client/src/shared/apis/setting/axiosInstance.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 75
File: apps/extension/src/apis/axiosInstance.ts:30-34
Timestamp: 2025-09-11T11:48:10.615Z
Learning: Pinback 프로젝트에서는 사용자 이메일 저장 시 'email' 키를 사용하도록 통일했습니다 (localStorage 및 chrome.storage.local 모두).
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: storybook
🔇 Additional comments (1)
apps/client/package.json (1)

32-32: LGTM! Chrome API 타입 정의 추가가 적절합니다.

Chrome storage API 사용을 위한 타입 정의가 devDependency로 올바르게 추가되었습니다.

Comment on lines 24 to 28
if (typeof chrome !== 'undefined' && chrome.storage?.local) {
chrome.storage.local.set({ token: newToken }, () => {
console.log('Token saved to chrome storage');
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Chrome storage 저장이 완료되기 전에 토큰이 반환될 수 있습니다.

chrome.storage.local.set은 비동기 작업이지만 대기하지 않고 즉시 토큰을 반환합니다. 이로 인해 Chrome storage에 저장이 완료되기 전에 토큰이 사용될 수 있으며, 저장 실패 시에도 감지할 수 없습니다.

동일한 패턴이 다음 파일에도 적용됩니다:

  • GoogleCallback.tsx (lines 30-34)
  • queries.ts (lines 83-87)
🔎 Promise 기반으로 변경하는 제안
     if (newToken) {
       localStorage.setItem('token', newToken);
       if (typeof chrome !== 'undefined' && chrome.storage?.local) {
-        chrome.storage.local.set({ token: newToken }, () => {
-          console.log('Token saved to chrome storage');
-        });
+        try {
+          await chrome.storage.local.set({ token: newToken });
+          console.log('Token saved to chrome storage');
+        } catch (error) {
+          console.error('Chrome storage 저장 실패:', error);
+        }
       }
       return newToken;
     }

또는 중앙화된 유틸리티 함수를 만드는 것을 권장합니다:

// shared/utils/storage.ts
export const saveToken = async (token: string): Promise<void> => {
  localStorage.setItem('token', token);
  
  if (typeof chrome !== 'undefined' && chrome.storage?.local) {
    try {
      await chrome.storage.local.set({ token });
      console.log('Token saved to chrome storage');
    } catch (error) {
      console.error('Chrome storage 저장 실패:', error);
      // localStorage는 성공했으므로 계속 진행
    }
  }
};

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/client/src/shared/apis/setting/axiosInstance.ts around lines 24-28 (and
similarly in GoogleCallback.tsx lines 30-34 and queries.ts lines 83-87), the
chrome.storage.local.set call is asynchronous but the code returns the token
immediately; change the implementation to an async/promise-based flow so callers
await storage completion and detect failures: create a centralized utility
(e.g., shared/utils/storage.ts) that writes to localStorage synchronously, wraps
chrome.storage.local.set in a Promise (using the callback or chrome.storage API
that returns a Promise), awaits it, logs success, and catches/logs errors
without blocking localStorage success; update these three files to import and
await that saveToken(token) before returning/using the token.

Copy link
Collaborator

@jjangminii jjangminii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로그인할 때 따로 익스텐션도 설정해야하는지 까먹고있었는데 추가해주셔서 감사합니당..

if (isUser) {
if (accessToken) {
localStorage.setItem('token', accessToken);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

크론도 따로 추가해줘야하는지 몰랐어요..반성하겠습니다

Copy link
Member

@constantly-dev constantly-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다! 간단한 코멘트만 확인부탁드려요~~

Comment on lines +30 to +34
if (typeof chrome !== 'undefined' && chrome.storage?.local) {
chrome.storage.local.set({ token: accessToken }, () => {
console.log('Token saved to chrome storage');
});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

크게 console이 필요없다면 지워도 될 것 같아요!
그리고 추가로 typeof chrome !== 'undefined' && chrome.storage?.local이 조건은 어떤 조건인가요??
이름을 붙이는 것도 좋을 것 같아요!

Comment on lines 81 to +87
if (newToken) {
localStorage.setItem('token', newToken);
if (typeof chrome !== 'undefined' && chrome.storage?.local) {
chrome.storage.local.set({ token: newToken }, () => {
console.log('Token saved to chrome storage');
});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

localStorage set 하는 곳에서 chrome storage도 다 같이 해줘야 하니, 애초에 이 두개를 같이 하는 util을 추상화 시켜서 사용하면 좋을 것 같아요.

스프린트 작업 대충 끝나면 Storage를 class형태나 util로 빼서 재사용 하도록 만드는 것이 좋을 것 같은데 어떻게 생각하시나요?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
apps/extension/src/apis/axiosInstance.ts (1)

28-32: 환경변수 분리에 대한 TODO가 확인됩니다.

하드코딩된 URL을 환경변수로 분리하는 것이 좋겠지만, TODO 주석으로 이미 인지하고 있으므로 향후 개선 사항으로 처리 가능합니다.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb5130a and 231a7b4.

📒 Files selected for processing (2)
  • apps/client/src/shared/apis/setting/axiosInstance.ts
  • apps/extension/src/apis/axiosInstance.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: storybook
🔇 Additional comments (3)
apps/client/src/shared/apis/setting/axiosInstance.ts (1)

12-20: 요청 인터셉터 단순화가 적절합니다.

토큰 재발급 로직을 제거하고 localStorage에서 토큰을 읽어 Bearer 토큰으로 첨부하는 표준 패턴으로 단순화되었습니다. 구현이 올바르고 명확합니다.

apps/extension/src/apis/axiosInstance.ts (2)

18-26: 요청 인터셉터 로직이 올바르게 구현되었습니다.

토큰이 존재할 때만 Authorization 헤더를 추가하는 조건부 로직이 적절합니다. getTokenFromStorage의 에러 핸들링이 개선되면 더욱 안정적으로 동작할 것입니다.


41-48: 인증 불필요 경로 목록에 Google OAuth 엔드포인트가 올바르게 추가되었습니다.

/api/v2/auth/google 경로를 noAuthNeeded 배열에 추가한 것은 Google 소셜 로그인 플로우에 적합합니다.

Comment on lines +46 to +47
localStorage.removeItem('token');
window.location.href = '/onboarding?step=SOCIAL_LOGIN';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Chrome storage도 함께 정리해야 합니다.

이 PR은 온보딩 시 토큰을 localStorage와 chrome.storage 양쪽에 저장하도록 변경합니다. 하지만 인증 오류(401/403) 발생 시 localStorage만 삭제하고 chrome.storage는 정리하지 않아 두 저장소 간 불일치가 발생합니다.

🔎 chrome.storage도 정리하는 수정안
      originalRequest._retry = true;

      localStorage.removeItem('token');
+     if (typeof chrome !== 'undefined' && chrome.storage?.local) {
+       chrome.storage.local.remove('token', () => {
+         console.log('Token removed from chrome storage');
+       });
+     }
      window.location.href = '/onboarding?step=SOCIAL_LOGIN';

      return Promise.reject(error);

또는 이전 리뷰 코멘트에서 제안된 중앙화된 유틸리티 함수를 사용하는 것을 권장합니다:

// shared/utils/storage.ts에 추가
export const removeToken = async (): Promise<void> => {
  localStorage.removeItem('token');
  
  if (typeof chrome !== 'undefined' && chrome.storage?.local) {
    try {
      await chrome.storage.local.remove('token');
      console.log('Token removed from chrome storage');
    } catch (error) {
      console.error('Chrome storage 삭제 실패:', error);
    }
  }
};

그 다음 이 파일에서:

      originalRequest._retry = true;

-     localStorage.removeItem('token');
+     await removeToken();
      window.location.href = '/onboarding?step=SOCIAL_LOGIN';

      return Promise.reject(error);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
localStorage.removeItem('token');
window.location.href = '/onboarding?step=SOCIAL_LOGIN';
localStorage.removeItem('token');
if (typeof chrome !== 'undefined' && chrome.storage?.local) {
chrome.storage.local.remove('token', () => {
console.log('Token removed from chrome storage');
});
}
window.location.href = '/onboarding?step=SOCIAL_LOGIN';
🤖 Prompt for AI Agents
In apps/client/src/shared/apis/setting/axiosInstance.ts around lines 46-47, the
code only clears localStorage on auth errors but leaves chrome.storage.token
intact; update the error handling to also remove the token from chrome.storage
(or call the centralized utility shared/utils/storage.removeToken if available)
and await its completion before redirecting to '/onboarding?step=SOCIAL_LOGIN';
ensure you guard for typeof chrome !== 'undefined' and chrome.storage?.local and
catch/log any chrome.storage errors so redirect still occurs even if chrome
removal fails.

Comment on lines +10 to +16
const getTokenFromStorage = () => {
return new Promise<string | undefined>((resolve) => {
chrome.storage.local.get('token', (result) => {
resolve(result.token);
});
});
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

런타임 안전성 검사 및 에러 핸들링이 누락되었습니다.

PR objectives에서 명시한 대로 chrome API 호출 전에 TypeError 방지를 위한 조건문이 필요합니다. 또한 chrome.storage.local.get 실패 시 에러 처리가 없어 Promise가 영원히 pending 상태가 될 수 있습니다.

🔎 제안하는 수정안
 const getTokenFromStorage = () => {
   return new Promise<string | undefined>((resolve, reject) => {
+    if (typeof chrome === 'undefined' || !chrome.storage?.local) {
+      resolve(undefined);
+      return;
+    }
+
-    chrome.storage.local.get('token', (result) => {
+    chrome.storage.local.get('token', (result) => {
+      if (chrome.runtime.lastError) {
+        reject(chrome.runtime.lastError);
+        return;
+      }
       resolve(result.token);
     });
   });
 };
🤖 Prompt for AI Agents
In apps/extension/src/apis/axiosInstance.ts around lines 10-16,
getTokenFromStorage lacks runtime checks for the chrome API and has no error
handling which can cause TypeError or a permanently pending Promise; update the
function to first check that window.chrome and chrome.storage and
chrome.storage.local exist (return undefined if absent), wrap
chrome.storage.local.get in a try/catch or provide the optional error callback
to handle failures and ensure the Promise always resolves or rejects (resolve
undefined on error), and consider adding a short timeout fallback so the Promise
cannot remain pending indefinitely.

? 'http://localhost:5173/onboarding?step=SOCIAL_LOGIN'
: 'https://pinback.today/onboarding?step=SOCIAL_LOGIN';

let isRedirecting = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

리다이렉트 플래그에 잠재적 경쟁 조건이 있습니다.

모듈 레벨의 isRedirecting 플래그는 여러 요청이 동시에 401/403을 받을 경우 제대로 동작하지 않을 수 있습니다. 또한 고정된 2초 타임아웃에 의존하여 플래그를 리셋하는 것은 탭 생성이 실패하거나 지연될 경우 문제가 될 수 있습니다.

💡 개선 제안
-let isRedirecting = false;
+let redirectPromise: Promise<void> | null = null;

그리고 응답 인터셉터에서:

-      if (!isRedirecting) {
-        isRedirecting = true;
+      if (!redirectPromise) {
+        redirectPromise = new Promise((resolve) => {
+          chrome.storage.local.remove(['token', 'email'], () => {});
 
-        chrome.storage.local.remove(['token', 'email'], () => {});
-
-        chrome.tabs.create({ url: onboardingUrl }, () => {
-          setTimeout(() => {
-            isRedirecting = false;
-          }, 2000);
-        });
+          chrome.tabs.create({ url: onboardingUrl }, () => {
+            redirectPromise = null;
+            resolve();
+          });
+        });
       }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +55 to +65
if (!isRedirecting) {
isRedirecting = true;

chrome.storage.local.remove(['token', 'email'], () => {});

chrome.tabs.create({ url: onboardingUrl }, () => {
setTimeout(() => {
isRedirecting = false;
}, 2000);
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Chrome API 호출에 에러 핸들링과 런타임 검사가 누락되었습니다.

chrome.storage.local.removechrome.tabs.create 호출에서 실패 케이스를 처리하지 않고 있으며, PR objectives에서 명시한 런타임 안전성 검사도 없습니다.

🔎 제안하는 수정안
       if (!isRedirecting) {
         isRedirecting = true;
 
-        chrome.storage.local.remove(['token', 'email'], () => {});
+        if (typeof chrome !== 'undefined' && chrome.storage?.local) {
+          chrome.storage.local.remove(['token', 'email'], () => {
+            if (chrome.runtime.lastError) {
+              console.error('토큰 제거 실패:', chrome.runtime.lastError);
+            }
+          });
+        }
 
-        chrome.tabs.create({ url: onboardingUrl }, () => {
-          setTimeout(() => {
-            isRedirecting = false;
-          }, 2000);
-        });
+        if (typeof chrome !== 'undefined' && chrome.tabs?.create) {
+          chrome.tabs.create({ url: onboardingUrl }, () => {
+            if (chrome.runtime.lastError) {
+              console.error('탭 생성 실패:', chrome.runtime.lastError);
+            }
+            setTimeout(() => {
+              isRedirecting = false;
+            }, 2000);
+          });
+        } else {
+          isRedirecting = false;
+        }
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!isRedirecting) {
isRedirecting = true;
chrome.storage.local.remove(['token', 'email'], () => {});
chrome.tabs.create({ url: onboardingUrl }, () => {
setTimeout(() => {
isRedirecting = false;
}, 2000);
});
}
if (!isRedirecting) {
isRedirecting = true;
if (typeof chrome !== 'undefined' && chrome.storage?.local) {
chrome.storage.local.remove(['token', 'email'], () => {
if (chrome.runtime.lastError) {
console.error('토큰 제거 실패:', chrome.runtime.lastError);
}
});
}
if (typeof chrome !== 'undefined' && chrome.tabs?.create) {
chrome.tabs.create({ url: onboardingUrl }, () => {
if (chrome.runtime.lastError) {
console.error('탭 생성 실패:', chrome.runtime.lastError);
}
setTimeout(() => {
isRedirecting = false;
}, 2000);
});
} else {
isRedirecting = false;
}
}
🤖 Prompt for AI Agents
In apps/extension/src/apis/axiosInstance.ts around lines 55-65, the chrome API
calls lack runtime existence checks and error handling; guard that chrome,
chrome.storage?.local and chrome.tabs exist before calling, check
chrome.runtime?.lastError inside each callback, and handle failures (log/report
and ensure isRedirecting is reset on error); also propagate or handle callback
errors instead of ignoring empty callbacks and ensure setTimeout still clears
isRedirecting if chrome.tabs.create fails.

@jllee000 jllee000 merged commit a6800bb into develop Dec 22, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix 버그 수정하라 러브버그

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fix] 온보딩 페이지 - 크롬스토리지 저장 추가

4 participants