Skip to content

fix(web): 닉네임 중복 토스트 이슈 포함 react-hot-toast 전면 전환#506

Open
manNomi wants to merge 2 commits intomainfrom
codex/migrate-react-hot-toast
Open

fix(web): 닉네임 중복 토스트 이슈 포함 react-hot-toast 전면 전환#506
manNomi wants to merge 2 commits intomainfrom
codex/migrate-react-hot-toast

Conversation

@manNomi
Copy link
Copy Markdown
Contributor

@manNomi manNomi commented Apr 30, 2026

관련 이슈

작업 내용

  • 기존 Zustand 기반 토스트 시스템을 제거하고 react-hot-toast 단일 체계로 전환했습니다.
  • 루트 레이아웃에서 <Toaster />를 1회만 마운트하도록 변경했습니다.
  • 네트워크 에러 토스트를 QueryClient 전역 queryCache/mutationCache onError로 일원화했습니다.
  • 인증(401) 케이스는 전역 에러 토스트에서 제외해 로그인 리다이렉트 토스트와 중복되지 않도록 처리했습니다.
  • 반복 발생하는 동일 에러 토스트는 id 기반 dedupe를 적용했습니다.
  • toast.info 의미 유지를 위해 공통 옵션(infoToastOptions, warningToastOptions)을 추가했습니다.
  • API 훅/개별 mutation의 중복 에러 토스트 코드를 제거하고, 성공 토스트 및 비즈니스 로직은 유지했습니다.
  • 레거시 코드 삭제:
    • apps/web/src/lib/zustand/useToastStore.ts
    • apps/web/src/components/ui/Toast/index.tsx
    • apps/web/src/utils/errorHandler.ts

특이 사항

  • 네트워크 실패 메시지는 화면별 개별 onError보다 전역 정책 메시지를 우선합니다.
  • 로컬 입력 검증 토스트(네트워크 무관)는 기존처럼 유지됩니다.
  • 닉네임 중복 등 동일 실패 상황에서 중첩 토스트가 누적되지 않도록 전역 중복 제어를 적용했습니다.

리뷰 요구사항 (선택)

  • 닉네임 중복/회원가입 실패 시 토스트가 1회만 노출되는지 확인 부탁드립니다.
  • 인증 만료 경로에서 “리다이렉트 토스트 + 전역 에러 토스트”가 중복되지 않는지 확인 부탁드립니다.
  • 대표 시나리오(로그인 실패, 커뮤니티 작성 실패, 지원 제출 실패)에서 토스트 UX가 기존 의도와 맞는지 확인 부탁드립니다.

검증

  • pnpm --filter @solid-connect/web run ci:check
  • pnpm --filter @solid-connect/web run build

@manNomi manNomi requested review from enunsnv and wibaek as code owners April 30, 2026 08:59
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

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

Project Deployment Actions Updated (UTC)
solid-connection-web Ready Ready Preview, Comment Apr 30, 2026 9:21am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
solid-connect-web-admin Skipped Skipped Apr 30, 2026 9:21am

@github-actions github-actions Bot added the web label Apr 30, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

Warning

Rate limit exceeded

@manNomi has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 40 minutes and 40 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: aef2253f-9e5d-4e93-9f4e-e60dc1c5ea0a

📥 Commits

Reviewing files that changed from the base of the PR and between 2a3320d and 4cf3c44.

📒 Files selected for processing (3)
  • apps/web/src/apis/image-upload/postUploadProfileImage.ts
  • apps/web/src/lib/react-query/errorToastMeta.ts
  • apps/web/src/lib/react-query/queryClient.ts

Walkthrough

이 변경사항은 기존 Zustand 기반 토스트 시스템을 react-hot-toast 라이브러리로 완전히 교체하는 대규모 마이그레이션입니다. 세부 내용은 다음과 같습니다:

  1. 의존성 추가

    • react-hot-toast 패키지를 package.json 런타임 의존성에 추가
  2. 레거시 토스트 시스템 제거

    • useToastStore.ts (Zustand 스토어) 완전 삭제
    • Toast/index.tsx (커스텀 토스트 UI 컴포넌트) 완전 삭제
    • errorHandler.ts (통합 에러 핸들러 유틸) 완전 삭제
  3. 광범위한 마이그레이션

    • 50개 이상의 파일에서 토스트 임포트를 useToastStore에서 react-hot-toast로 변경
    • API 훅 및 컴포넌트에서 뮤테이션 onError 콜백 제거
  4. 글로벌 에러 처리 업데이트

    • queryClient.ts에서 React Query 캐시 에러 핸들러를 react-hot-toast 기반으로 개선
    • 401 오류 필터링 및 중복 토스트 방지 로직 구현
  5. UI 업데이트

    • app/layout.tsx에서 Toaster 컴포넌트로 토스트 렌더링 교체
    • 새로운 lib/toast/options.ts에서 infoToastOptions/warningToastOptions 정의

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • wibaek
  • enunsnv
  • khwww
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경사항을 명확하게 요약하고 있습니다. Zustand 기반 토스트를 react-hot-toast로 전환하고 닉네임 중복 토스트 이슈를 해결한다는 핵심 내용이 잘 드러나 있습니다.
Description check ✅ Passed PR 설명이 모든 필수 섹션(관련 이슈, 작업 내용, 특이 사항, 리뷰 요구사항)을 포함하고 있으며, 변경사항을 충분히 상세하게 설명하고 있습니다.
Linked Issues check ✅ Passed PR의 모든 코드 변경사항이 #502 이슈의 목표인 '닉네임 중복 토스트 중복 방지'를 직접적으로 해결하고 있습니다. 전역 에러 토스트에 id 기반 dedupe 처리를 적용하여 동일 에러 반복 발생 시 중복 토스트가 누적되지 않도록 구현했습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 Zustand 토스트 시스템의 react-hot-toast 전환이라는 명시된 목표와 #502 이슈 해결이라는 범위 내에 있습니다. 토스트 관련 코드만 수정되었으며, 비즈니스 로직이나 다른 기능에 대한 범위 외 변경은 없습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/migrate-react-hot-toast

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
Review rate limit: 0/1 reviews remaining, refill in 40 minutes and 40 seconds.

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

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2a3320d2e9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

const axiosError = error as AxiosError<ErrorResponse>;
const status = axiosError?.response?.status;
if (status === 401) return; // 인증 오류는 토스트 표시 X
if (isUnauthorized(status)) return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Skip auth-gated interceptor errors in global toast handler

axiosInstance can reject with AuthenticationRequiredError after already showing the login-redirect toast (redirectToLogin(...)), but this handler only suppresses status === 401. Because AuthenticationRequiredError has no HTTP status, it falls through and triggers toast.error(error.message), so users can see an extra generic "Authentication required" toast on top of the redirect message whenever protected requests run without a token. Add a guard for this auth-redirect error path (and apply it to both query and mutation cache handlers) before emitting global error toasts.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/web/src/apis/news/deleteNews.ts (1)

23-37: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

  1. 롤백 시 캐시 데이터 형태가 깨질 수 있습니다.

Line 23에서 Article[]를 저장하고 Line 37에서 동일 키에 Article[]를 복구하지만, 같은 키를 Line 25에서는 ArticleListResponse로 다루고 있습니다. 실패 롤백 이후 newsResponseList를 기대하는 화면에서 런타임 오류가 날 수 있습니다.

🔧 제안 패치
 type ArticleDeleteMutationContext = {
-  previousArticleList?: Article[];
+  previousArticleContainer?: ArticleListResponse;
 };

 ...
-      const previousArticleList = queryClient.getQueryData<Article[]>(queryKey);
+      const previousArticleContainer = queryClient.getQueryData<ArticleListResponse>(queryKey);

       queryClient.setQueryData<ArticleListResponse>(queryKey, (oldData) => {
         if (!oldData) return { newsResponseList: [] };
         return {
           newsResponseList: oldData.newsResponseList.filter((article) => article.id !== deletedArticleId),
         };
       });

-      return { previousArticleList };
+      return { previousArticleContainer };
     },

     onError: (_error, _variables, context) => {
-      if (context?.previousArticleList) {
-        queryClient.setQueryData<Article[]>(queryKey, context.previousArticleList);
+      if (context?.previousArticleContainer) {
+        queryClient.setQueryData<ArticleListResponse>(queryKey, context.previousArticleContainer);
       }
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/apis/news/deleteNews.ts` around lines 23 - 37, The rollback
corrupts cache shape: you fetch previousArticleList as Article[] via
queryClient.getQueryData but you update the cache as ArticleListResponse (with
newsResponseList) in the mutation and later restore the raw Article[] in
onError; instead capture and restore the same shape used by setQueryData. Change
the optimistic snapshot to read previousData as ArticleListResponse (or wrap the
Article[] as { newsResponseList }) and in onError restore that
ArticleListResponse to the same queryKey so the UI still finds newsResponseList;
adjust references to previousArticleList, getQueryData, setQueryData,
ArticleListResponse and newsResponseList accordingly.
apps/web/src/apis/news/putUpdateNews.ts (1)

21-24: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

1) 롤백 캐시 타입 불일치로 실패 시 캐시 shape가 깨질 수 있습니다.

  • Line 21에서 스냅샷을 Article[]로 저장하고, Line 23에서는 ArticleListResponse를 캐시에 쓰고 있습니다.
  • 이후 Line 47에서 Article[]를 그대로 복원하면 newsResponseList 구조가 사라져 조회 코드가 깨질 수 있습니다.
🔧 제안 수정안
 type ArticleMutationContext = {
-  previousArticleList?: Article[];
+  previousArticleList?: ArticleListResponse;
 };
@@
-      const previousArticleList = queryClient.getQueryData<Article[]>(queryKey);
+      const previousArticleList = queryClient.getQueryData<ArticleListResponse>(queryKey);
@@
-        queryClient.setQueryData(queryKey, context.previousArticleList);
+        queryClient.setQueryData<ArticleListResponse>(queryKey, context.previousArticleList);

Also applies to: 45-48

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/apis/news/putUpdateNews.ts` around lines 21 - 24,
previousArticleList is saved as Article[] but setQueryData expects an
ArticleListResponse, causing rollback to restore the wrong shape and break
consumers; change the snapshot to capture the same shape you write
(ArticleListResponse) or, when saving the Article[] snapshot, wrap it into {
newsResponseList: previousArticleList } before calling setQueryData. Locate the
queryClient usage in putUpdateNews.ts (variables: previousArticleList, queryKey,
setQueryData) and update both places where you save/restore the cache (including
the other occurrence similar at lines 45-48) so the rollback always restores an
ArticleListResponse object shape.
🧹 Nitpick comments (1)
apps/web/src/app/university/score/submit/language-test/LanguageTestSubmitForm.tsx (1)

55-56: React Query 패턴을 더 명확하게 따르도록 mutate + onSuccess 콜백으로 변경해 주세요.

현재 코드의 빈 catch 블록은 작동하지만, 이 프로젝트의 React Query 전역 에러 처리 패턴과 맞지 않습니다. 다음과 같이 정리하면 의도가 더 명확하고 유지보수하기 좋습니다:

  1. mutateAsyncmutate 로 변경
  2. 폼 제출 핸들러를 async에서 동기 함수로 단순화
  3. mutate 호출 시 onSuccess 콜백으로 성공 상태 관리
  4. try-catch 제거 (에러는 전역 핸들러가 이미 처리 중)
🔧 제안 diff
-  const { mutateAsync: postLanguageTestScore } = usePostLanguageTestScore();
+  const { mutate: postLanguageTestScore } = usePostLanguageTestScore();

-  const onSubmit: SubmitHandler<LanguageTestFormData> = async (data) => {
-    try {
-      await postLanguageTestScore({
-        languageTestScoreRequest: {
-          languageTestType: data.testType,
-          languageTestScore: data.score,
-          issueDate: "2025-01-01",
-        },
-        file: data.file[0],
-      });
-
-      // 성공 시에만 실행
-      reset();
-      setShowResult(true);
-      setSubmittedData(data);
-    } catch (_error) {
-      // 실패 토스트는 React Query 전역 onError에서 단일 처리
-    }
-  };
+  const onSubmit: SubmitHandler<LanguageTestFormData> = (data) => {
+    postLanguageTestScore(
+      {
+        languageTestScoreRequest: {
+          languageTestType: data.testType,
+          languageTestScore: data.score,
+          issueDate: "2025-01-01",
+        },
+        file: data.file[0],
+      },
+      {
+        onSuccess: () => {
+          reset();
+          setShowResult(true);
+          setSubmittedData(data);
+        },
+      },
+    );
+  };

프로젝트의 전역 에러 처리 설정이 이미 모든 mutation 실패를 담당하고 있으므로, mutate만으로 충분합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/web/src/app/university/score/submit/language-test/LanguageTestSubmitForm.tsx`
around lines 55 - 56, The submit handler in LanguageTestSubmitForm currently
uses mutateAsync with an empty catch; change it to call the mutation's mutate
(not mutateAsync), make handleSubmit synchronous (remove async/await and the
try-catch block), and pass an onSuccess callback to mutate to update success
state (e.g., call setIsSubmitted(true) or whatever success handler you already
have). Locate the useMutation instance (the submit mutation used in
LanguageTestSubmitForm) and replace its mutateAsync usage with
mutate({...payload}, { onSuccess: () => { /* success handling */ }}) so global
React Query error handling remains responsible for failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/web/src/apis/news/deleteNews.ts`:
- Around line 23-37: The rollback corrupts cache shape: you fetch
previousArticleList as Article[] via queryClient.getQueryData but you update the
cache as ArticleListResponse (with newsResponseList) in the mutation and later
restore the raw Article[] in onError; instead capture and restore the same shape
used by setQueryData. Change the optimistic snapshot to read previousData as
ArticleListResponse (or wrap the Article[] as { newsResponseList }) and in
onError restore that ArticleListResponse to the same queryKey so the UI still
finds newsResponseList; adjust references to previousArticleList, getQueryData,
setQueryData, ArticleListResponse and newsResponseList accordingly.

In `@apps/web/src/apis/news/putUpdateNews.ts`:
- Around line 21-24: previousArticleList is saved as Article[] but setQueryData
expects an ArticleListResponse, causing rollback to restore the wrong shape and
break consumers; change the snapshot to capture the same shape you write
(ArticleListResponse) or, when saving the Article[] snapshot, wrap it into {
newsResponseList: previousArticleList } before calling setQueryData. Locate the
queryClient usage in putUpdateNews.ts (variables: previousArticleList, queryKey,
setQueryData) and update both places where you save/restore the cache (including
the other occurrence similar at lines 45-48) so the rollback always restores an
ArticleListResponse object shape.

---

Nitpick comments:
In
`@apps/web/src/app/university/score/submit/language-test/LanguageTestSubmitForm.tsx`:
- Around line 55-56: The submit handler in LanguageTestSubmitForm currently uses
mutateAsync with an empty catch; change it to call the mutation's mutate (not
mutateAsync), make handleSubmit synchronous (remove async/await and the
try-catch block), and pass an onSuccess callback to mutate to update success
state (e.g., call setIsSubmitted(true) or whatever success handler you already
have). Locate the useMutation instance (the submit mutation used in
LanguageTestSubmitForm) and replace its mutateAsync usage with
mutate({...payload}, { onSuccess: () => { /* success handling */ }}) so global
React Query error handling remains responsible for failures.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c5595e3a-c1de-4daa-8c3b-f06453584c37

📥 Commits

Reviewing files that changed from the base of the PR and between 936cd22 and 2a3320d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (60)
  • apps/web/package.json
  • apps/web/src/apis/Auth/deleteAccount.ts
  • apps/web/src/apis/Auth/postAppleAuth.ts
  • apps/web/src/apis/Auth/postEmailLogin.ts
  • apps/web/src/apis/Auth/postEmailVerification.ts
  • apps/web/src/apis/Auth/postKakaoAuth.ts
  • apps/web/src/apis/Auth/postSignUp.ts
  • apps/web/src/apis/MyPage/patchPassword.ts
  • apps/web/src/apis/MyPage/patchProfile.ts
  • apps/web/src/apis/Scores/postCreateGpa.ts
  • apps/web/src/apis/Scores/postCreateLanguageTest.ts
  • apps/web/src/apis/applications/postSubmitApplication.ts
  • apps/web/src/apis/community/deleteComment.ts
  • apps/web/src/apis/community/deleteLikePost.ts
  • apps/web/src/apis/community/deletePost.ts
  • apps/web/src/apis/community/patchUpdatePost.ts
  • apps/web/src/apis/community/postCreateComment.ts
  • apps/web/src/apis/community/postCreatePost.ts
  • apps/web/src/apis/community/postLikePost.ts
  • apps/web/src/apis/image-upload/postUploadProfileImageBeforeSignup.ts
  • apps/web/src/apis/mentor/postApplyMentoring.ts
  • apps/web/src/apis/mentor/postMentorApplication.ts
  • apps/web/src/apis/news/deleteNews.ts
  • apps/web/src/apis/news/postCreateNews.ts
  • apps/web/src/apis/news/putUpdateNews.ts
  • apps/web/src/apis/reports/postReport.ts
  • apps/web/src/apis/universities/postAddWish.ts
  • apps/web/src/app/(home)/_ui/FindLastYearScoreBar/index.tsx
  • apps/web/src/app/community/[boardCode]/[postId]/KebabMenu.tsx
  • apps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsx
  • apps/web/src/app/community/[boardCode]/create/PostForm.tsx
  • apps/web/src/app/community/_hooks/useCommunityImageUpload.ts
  • apps/web/src/app/layout.tsx
  • apps/web/src/app/login/LoginContent.tsx
  • apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx
  • apps/web/src/app/my/_ui/MyProfileContent/index.tsx
  • apps/web/src/app/my/apply-mentor/_components/UniversityScreen/index.tsx
  • apps/web/src/app/my/apply-mentor/page.tsx
  • apps/web/src/app/my/favorite/_ui/FavoriteContent/_hooks/useSelectUniversities.ts
  • apps/web/src/app/sign-up/email/EmailSignUpForm.tsx
  • apps/web/src/app/university/[homeUniversity]/[id]/_ui/UniversityDetail/_ui/UniversityBtns.tsx
  • apps/web/src/app/university/application/apply/ApplyPageContent.tsx
  • apps/web/src/app/university/application/apply/GpaStep.tsx
  • apps/web/src/app/university/application/apply/LanguageStep.tsx
  • apps/web/src/app/university/score/ScoreCard.tsx
  • apps/web/src/app/university/score/submit/language-test/LanguageTestSubmitForm.tsx
  • apps/web/src/components/layout/GlobalLayout/ui/AIInspectorFab/index.tsx
  • apps/web/src/components/login/signup/SignupPrepareScreen.tsx
  • apps/web/src/components/login/signup/SignupProfileScreen.tsx
  • apps/web/src/components/login/signup/SignupRegionScreen.tsx
  • apps/web/src/components/login/signup/SignupSurvey.tsx
  • apps/web/src/components/modal/SurveyModal.tsx
  • apps/web/src/components/ui/ReportPanel/_hooks/useSelectReportHandler.ts
  • apps/web/src/components/ui/Toast/index.tsx
  • apps/web/src/lib/react-query/queryClient.ts
  • apps/web/src/lib/toast/options.ts
  • apps/web/src/lib/zustand/useToastStore.ts
  • apps/web/src/utils/authUtils.ts
  • apps/web/src/utils/axiosInstance.ts
  • apps/web/src/utils/errorHandler.ts
💤 Files with no reviewable changes (14)
  • apps/web/src/apis/universities/postAddWish.ts
  • apps/web/src/apis/mentor/postMentorApplication.ts
  • apps/web/src/apis/image-upload/postUploadProfileImageBeforeSignup.ts
  • apps/web/src/apis/mentor/postApplyMentoring.ts
  • apps/web/src/apis/applications/postSubmitApplication.ts
  • apps/web/src/components/ui/ReportPanel/_hooks/useSelectReportHandler.ts
  • apps/web/src/apis/Auth/postSignUp.ts
  • apps/web/src/apis/community/deleteLikePost.ts
  • apps/web/src/apis/community/postLikePost.ts
  • apps/web/src/lib/zustand/useToastStore.ts
  • apps/web/src/apis/Auth/postEmailVerification.ts
  • apps/web/src/apis/Auth/deleteAccount.ts
  • apps/web/src/components/ui/Toast/index.tsx
  • apps/web/src/utils/errorHandler.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4cf3c4483b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +42 to +43
// 인증 오류는 인터셉터 리다이렉트 토스트에서만 처리
if (isUnauthorized(status)) return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not suppress all 401 mutation toasts globally

The new global if (isUnauthorized(status)) return; in mutation errors drops every 401 toast, but not all 401s are interceptor redirect cases. Public-auth mutations like usePostEmailAuth (apps/web/src/apis/Auth/postEmailLogin.ts) now have no local onError toast, so a 401 from /auth/email/sign-in can fail silently (no redirect toast and no global toast). This regresses core login feedback for invalid/expired credentials unless each affected mutation adds its own error UI.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

닉네임 중복 toast 여러 개

1 participant