From 2827adda5de55d819d8ca00a0f44b58e6c4b6147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A1=EA=B8=B0=EC=A4=80?= Date: Sat, 8 Mar 2025 16:36:46 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[25.02.28=20/=20TASK-116,TASK-103]=20Modify?= =?UTF-8?q?=20-=20=EC=BA=90=EC=8B=9C=20=EC=B6=A9=EB=8F=8C=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20(#18)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * modify: 캐시 충돌 관련 이슈 해결 * modify: 로그아웃 시에도 캐시 잔존 오류 해결 * modify: 사소한 휴먼에러 해결 * refactor: 필요없는 주석 제거 --- src/apis/instance.request.ts | 3 +-- src/app/(with-tracker)/(login)/Content.tsx | 4 +--- src/components/auth-required/header/index.tsx | 12 ++++++++++-- .../auth-required/main/Section/index.tsx | 15 +++++---------- src/utils/queryUtil.ts | 2 +- src/utils/revalidateUtil.ts | 9 +++++++++ 6 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 src/utils/revalidateUtil.ts diff --git a/src/apis/instance.request.ts b/src/apis/instance.request.ts index 05ba80b..613fd03 100644 --- a/src/apis/instance.request.ts +++ b/src/apis/instance.request.ts @@ -75,10 +75,9 @@ export const instance = async ( return (data.body as unknown as SuccessType).data; } catch (err: unknown) { const context = err as Response; - if (location && !context.ok && context.status === 403) { + if (location && !context.ok && context.status === 401) { window.location.replace('/'); } - //context.status === 401 || setContext('Request', { path: context.url, status: context.status, diff --git a/src/app/(with-tracker)/(login)/Content.tsx b/src/app/(with-tracker)/(login)/Content.tsx index 8c63710..bad17fb 100644 --- a/src/app/(with-tracker)/(login)/Content.tsx +++ b/src/app/(with-tracker)/(login)/Content.tsx @@ -3,7 +3,7 @@ import { useRouter } from 'next/navigation'; import { useForm } from 'react-hook-form'; import Image from 'next/image'; -import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import { Input, Button } from '@/components'; import { LoginVo } from '@/types'; import { login, sampleLogin } from '@/apis'; @@ -14,7 +14,6 @@ const responsiveStyle = export const Content = () => { const { replace } = useRouter(); - const client = useQueryClient(); const { register, @@ -23,7 +22,6 @@ export const Content = () => { } = useForm({ mode: 'all' }); const onSuccess = () => { - client.clear(); trackUserEvent(MessageEnum.LOGIN); replace('/main?asc=false&sort='); }; diff --git a/src/components/auth-required/header/index.tsx b/src/components/auth-required/header/index.tsx index 6984f7b..530a488 100644 --- a/src/components/auth-required/header/index.tsx +++ b/src/components/auth-required/header/index.tsx @@ -9,6 +9,8 @@ import { NameType } from '@/components'; import { useResponsive } from '@/hooks'; import { logout, me } from '@/apis'; import { trackUserEvent, MessageEnum } from '@/utils/trackUtil'; +import { revalidate } from '@/utils/revalidateUtil'; + import { defaultStyle, Section, textStyle } from './Section'; const PARAMS = { @@ -37,13 +39,19 @@ export const Header = () => { const { mutate: out } = useMutation({ mutationFn: logout, - onMutate: () => router.replace('/'), - onSuccess: () => client.removeQueries(), + onSuccess: async () => { + await revalidate(); + client.clear(); + router.replace('/'); + }, }); const { data: profiles } = useQuery({ queryKey: [PATHS.ME], queryFn: me, + enabled: !!client.getQueryData([PATHS.ME]), + // 로그아웃 후 리렌더링되어 다시 fetch되는 경우 해결 + // 어차피 prefetch를 통해 데이터를 불러온 상태에서 렌더하기 때문에, 캐시 여부만 판단하면 됨 }); useEffect(() => { diff --git a/src/components/auth-required/main/Section/index.tsx b/src/components/auth-required/main/Section/index.tsx index 91ce6dc..bdb1c45 100644 --- a/src/components/auth-required/main/Section/index.tsx +++ b/src/components/auth-required/main/Section/index.tsx @@ -1,27 +1,22 @@ 'use client'; -import { useQueryClient } from '@tanstack/react-query'; import { useState } from 'react'; -import { UserNameNotFoundError } from '@/errors'; import { trackUserEvent, MessageEnum } from '@/utils/trackUtil'; import { parseNumber } from '@/utils/numberUtil'; import { COLORS, env, PATHS } from '@/constants'; import { PostType, UserDto } from '@/types'; import { Icon } from '@/components'; +import { getQueryClient } from '@/utils/queryUtil'; import { Graph } from './Graph'; export const Section = (p: PostType) => { const [open, setOpen] = useState(false); - const client = useQueryClient(); - const { username } = client.getQueryData([PATHS.ME]) as UserDto; - const URL = env.VELOG_URL; + const username = ( + getQueryClient().getQueryData([PATHS.ME]) as Partial + )?.username; - if (!username) { - throw new UserNameNotFoundError(); - } - - const url = `${URL}/@${username}/${p.slug}`; + const url = `${env.VELOG_URL}/@${username}/${p.slug}`; return (
diff --git a/src/utils/queryUtil.ts b/src/utils/queryUtil.ts index 9e40e0a..ad54707 100644 --- a/src/utils/queryUtil.ts +++ b/src/utils/queryUtil.ts @@ -3,7 +3,7 @@ import { toast } from 'react-toastify'; let localQueryClient: QueryClient | undefined; const STALE_TIME = 1000 * 60 * 3; -const GC_TIME = 1000; +const GC_TIME = 1000 * 60 * 20; const createQueryClient = () => new QueryClient({ diff --git a/src/utils/revalidateUtil.ts b/src/utils/revalidateUtil.ts new file mode 100644 index 0000000..375a030 --- /dev/null +++ b/src/utils/revalidateUtil.ts @@ -0,0 +1,9 @@ +'use server'; + +import { revalidatePath } from 'next/cache'; +import { redirect } from 'next/navigation'; + +export async function revalidate() { + revalidatePath('/', 'layout'); + redirect('/'); +} From 6a02bf26629a38387784c8018428271a66d5faf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A1=EA=B8=B0=EC=A4=80?= Date: Sat, 8 Mar 2025 16:37:03 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[24.03.06=20/=20TASK-133]=20Feature=20-=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20=EC=98=A4=EB=A5=98=20=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=A7=81=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=8D=BC=EB=B8=94?= =?UTF-8?q?=EB=A6=AC=EC=8B=B1=20(#21)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * modify: 캐시 충돌 관련 이슈 해결 * modify: 로그아웃 시에도 캐시 잔존 오류 해결 * modify: 사소한 휴먼에러 해결 * refactor: 필요없는 주석 제거 * feature: 서버 에러 핸들링 페이지 퍼블리싱 * feature: 순수 HTML 형태의 오류 페이지 제작 * modify: 빌드 오류 수정 * modify: 리뷰 반영 * refactor: 파일명 변경 --- 500.html | 180 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + pnpm-lock.yaml | 9 +++ 3 files changed, 190 insertions(+) create mode 100644 500.html diff --git a/500.html b/500.html new file mode 100644 index 0000000..56939b6 --- /dev/null +++ b/500.html @@ -0,0 +1,180 @@ + + + + + + Velog Dashboard - 500 + + + +
+
+
+ VD +
+

Velog Dashboard

+
+ 알 수 없는 오류가 발생했습니다. +
+ + + + diff --git a/package.json b/package.json index 186bf20..5409b0f 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dependencies": { "@channel.io/channel-web-sdk-loader": "^2.0.0", "@next/third-parties": "^15.1.7", + "@sentry/core": "^9.4.0", "@sentry/nextjs": "^8.47.0", "@tanstack/react-query": "^5.61.3", "@tanstack/react-query-devtools": "^5.62.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29ce0d1..85f3689 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@next/third-parties': specifier: ^15.1.7 version: 15.1.7(next@14.2.18(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@sentry/core': + specifier: ^9.4.0 + version: 9.4.0 '@sentry/nextjs': specifier: ^8.47.0 version: 8.47.0(@opentelemetry/core@1.30.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.0(@opentelemetry/api@1.9.0))(next@14.2.18(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.97.1) @@ -1499,6 +1502,10 @@ packages: resolution: {integrity: sha512-iSEJZMe3DOcqBFZQAqgA3NB2lCWBc4Gv5x/SCri/TVg96wAlss4VrUunSI2Mp0J4jJ5nJcJ2ChqHSBAU48k3FA==} engines: {node: '>=14.18'} + '@sentry/core@9.4.0': + resolution: {integrity: sha512-Edd/uWDGZ+1CMuVVWdxIOm1rBhzgpqiqz984TZu20wryoIoRsA8ZllUar6N+cWK17VusNY0OS2DozKO69y7fVQ==} + engines: {node: '>=18'} + '@sentry/nextjs@8.47.0': resolution: {integrity: sha512-qr++MBYhyAwF25hGq7LAxe3Xehs+w2V4b8mVxilRYFXNkWFazY1ukZcVzq9pKrrt5uTiURTf68e8eVMraHnHEQ==} engines: {node: '>=14.18'} @@ -6373,6 +6380,8 @@ snapshots: '@sentry/core@8.47.0': {} + '@sentry/core@9.4.0': {} + '@sentry/nextjs@8.47.0(@opentelemetry/core@1.30.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.0(@opentelemetry/api@1.9.0))(next@14.2.18(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.97.1)': dependencies: '@opentelemetry/api': 1.9.0 From f38f3dcfe44d459f334637c37e7008dc5b35ad3c Mon Sep 17 00:00:00 2001 From: six-standard Date: Sat, 8 Mar 2025 17:22:25 +0900 Subject: [PATCH 3/3] =?UTF-8?q?modify:=20=EB=B2=84=EC=A0=84=20=EB=A7=9E?= =?UTF-8?q?=EC=B6=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- pnpm-lock.yaml | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 5409b0f..e7ba121 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "dependencies": { "@channel.io/channel-web-sdk-loader": "^2.0.0", "@next/third-parties": "^15.1.7", - "@sentry/core": "^9.4.0", + "@sentry/core": "^8.47.0", "@sentry/nextjs": "^8.47.0", "@tanstack/react-query": "^5.61.3", "@tanstack/react-query-devtools": "^5.62.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85f3689..d4a63af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^15.1.7 version: 15.1.7(next@14.2.18(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@sentry/core': - specifier: ^9.4.0 - version: 9.4.0 + specifier: ^8.47.0 + version: 8.47.0 '@sentry/nextjs': specifier: ^8.47.0 version: 8.47.0(@opentelemetry/core@1.30.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.0(@opentelemetry/api@1.9.0))(next@14.2.18(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.97.1) @@ -1502,10 +1502,6 @@ packages: resolution: {integrity: sha512-iSEJZMe3DOcqBFZQAqgA3NB2lCWBc4Gv5x/SCri/TVg96wAlss4VrUunSI2Mp0J4jJ5nJcJ2ChqHSBAU48k3FA==} engines: {node: '>=14.18'} - '@sentry/core@9.4.0': - resolution: {integrity: sha512-Edd/uWDGZ+1CMuVVWdxIOm1rBhzgpqiqz984TZu20wryoIoRsA8ZllUar6N+cWK17VusNY0OS2DozKO69y7fVQ==} - engines: {node: '>=18'} - '@sentry/nextjs@8.47.0': resolution: {integrity: sha512-qr++MBYhyAwF25hGq7LAxe3Xehs+w2V4b8mVxilRYFXNkWFazY1ukZcVzq9pKrrt5uTiURTf68e8eVMraHnHEQ==} engines: {node: '>=14.18'} @@ -6380,8 +6376,6 @@ snapshots: '@sentry/core@8.47.0': {} - '@sentry/core@9.4.0': {} - '@sentry/nextjs@8.47.0(@opentelemetry/core@1.30.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.0(@opentelemetry/api@1.9.0))(next@14.2.18(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.97.1)': dependencies: '@opentelemetry/api': 1.9.0