diff --git a/app/(sub-page)/error.tsx b/app/(sub-page)/error.tsx new file mode 100644 index 00000000..a0bd7ef5 --- /dev/null +++ b/app/(sub-page)/error.tsx @@ -0,0 +1,32 @@ +'use client'; +import { useEffect } from 'react'; +import Link from 'next/link'; + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + useEffect(() => { + console.error(error); + }, [error]); + + if (error.message === 'Unauthorized') { + return ( +
+

Unauthorized

+ to Login +
+ ); + } + + return ( +
+

Something went wrong!!!!!

+ +
+ ); +} diff --git a/app/(sub-page)/protected/page.tsx b/app/(sub-page)/protected/page.tsx new file mode 100644 index 00000000..9fdf1a93 --- /dev/null +++ b/app/(sub-page)/protected/page.tsx @@ -0,0 +1,15 @@ +import { API_PATH } from '@/app/business/api-path'; +import { httpErrorHandler } from '@/app/utils/http/http-error-handler'; + +async function trigger() { + const response = await fetch(`${API_PATH.auth}/failure`, { + cache: 'no-store', + }); + const result = await response.json(); + httpErrorHandler(response, result); +} + +export default async function ProtectedPage() { + const data = await trigger(); + return
Auth protected
; +} diff --git a/app/business/user/user.command.ts b/app/business/user/user.command.ts index 9dbb86a6..33a1f833 100644 --- a/app/business/user/user.command.ts +++ b/app/business/user/user.command.ts @@ -15,7 +15,7 @@ import { cookies } from 'next/headers'; import { isValidation } from '@/app/utils/zod/validation.util'; import { redirect } from 'next/navigation'; -export async function validateToken(): Promise { +export async function validateToken(): Promise { const accessToken = cookies().get('accessToken')?.value; const refreshToken = cookies().get('refreshToken')?.value; try { diff --git a/app/global-error.tsx b/app/global-error.tsx new file mode 100644 index 00000000..dc545c80 --- /dev/null +++ b/app/global-error.tsx @@ -0,0 +1,27 @@ +'use client'; +import { useEffect } from 'react'; + +// https://nextjs.org/docs/app/building-your-application/routing/error-handling#handling-errors-in-root-layouts +// global-error는 프로덕션에서만 활성화 +export default function GlobalError({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) { + useEffect(() => { + // Log the error to an error reporting service + console.error(error); + }, [error]); + + return ( + + +

Something went wrong!!!!!

+ + + + ); +} diff --git a/app/mocks/handlers/user-handler.mock.ts b/app/mocks/handlers/user-handler.mock.ts index 61835740..bde7ac3a 100644 --- a/app/mocks/handlers/user-handler.mock.ts +++ b/app/mocks/handlers/user-handler.mock.ts @@ -22,6 +22,10 @@ function mockDecryptToken(token: string) { } export const userHandlers = [ + http.get(`${API_PATH.auth}/failure`, async ({ request }) => { + await delay(500); + return HttpResponse.json({ status: 401, message: 'Unauthorized' }, { status: 401 }); + }), http.post(`${API_PATH.auth}/token`, async ({ request }) => { return HttpResponse.json({ accessToken: 'fake-access-token', diff --git a/app/ui/view/molecule/list/swipeable-custom-list.tsx b/app/ui/view/molecule/list/swipeable-custom-list.tsx index 60f2c92d..296590c3 100644 --- a/app/ui/view/molecule/list/swipeable-custom-list.tsx +++ b/app/ui/view/molecule/list/swipeable-custom-list.tsx @@ -1,6 +1,6 @@ import React, { ReactNode } from 'react'; import { ListRow } from './list-root'; -import { SwipeableList, Type as ListType } from 'react-swipeable-list'; +// import { SwipeableList, Type as ListType } from 'react-swipeable-list'; interface SwipeableListProps { data: T[]; @@ -10,7 +10,7 @@ interface SwipeableListProps { export default function SwipeableCustomList({ data, render }: SwipeableListProps) { return (
- {data.map((item, index) => render(item, index))} + {/* {data.map((item, index) => render(item, index))} */}
); } diff --git a/app/ui/view/molecule/table/table.stories.tsx b/app/ui/view/molecule/table/table.stories.tsx index b3c32220..d90011fc 100644 --- a/app/ui/view/molecule/table/table.stories.tsx +++ b/app/ui/view/molecule/table/table.stories.tsx @@ -87,7 +87,7 @@ export const SwipeableLectureTable: StoryObj = { credit: 3, }, ]; - const actionButton = () => {}} />; + const actionButton = () => {}} />; return (