From 4d40fa1cf79e01ed5c1b1792b890f88a1e5cb369 Mon Sep 17 00:00:00 2001 From: "focp212@naver.com" Date: Fri, 31 Oct 2025 08:35:50 +0900 Subject: [PATCH] =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/common/ui/sort-type-box.tsx | 2 +- src/entities/home/ui/favorite-wrapper.tsx | 1 - src/entities/menu/ui/menu-category.tsx | 9 ++---- src/shared/configs/axios/index.ts | 29 ++++++++++------- src/shared/configs/axios/utils.ts | 10 ------ src/shared/configs/query.ts | 1 + .../common-error-boundary.tsx | 7 ++-- .../global-api-error-boundary.tsx | 32 ++++++++++++------- .../global-error-boundary.tsx | 4 ++- src/widgets/fallbacks/api-error.tsx | 19 +++++++---- src/widgets/fallbacks/common-error.tsx | 25 +++++++++------ src/widgets/fallbacks/kick-out-error.tsx | 26 +++++++++------ src/widgets/loadable/index.tsx | 17 ---------- 13 files changed, 92 insertions(+), 90 deletions(-) delete mode 100644 src/shared/configs/axios/utils.ts delete mode 100644 src/widgets/loadable/index.tsx diff --git a/src/entities/common/ui/sort-type-box.tsx b/src/entities/common/ui/sort-type-box.tsx index 0f3f067..29e6e1f 100644 --- a/src/entities/common/ui/sort-type-box.tsx +++ b/src/entities/common/ui/sort-type-box.tsx @@ -28,7 +28,7 @@ export const SortTypeBox = ({ } diff --git a/src/entities/home/ui/favorite-wrapper.tsx b/src/entities/home/ui/favorite-wrapper.tsx index 2b6f975..7167f65 100644 --- a/src/entities/home/ui/favorite-wrapper.tsx +++ b/src/entities/home/ui/favorite-wrapper.tsx @@ -5,7 +5,6 @@ import 'swiper/css'; import { IMAGE_ROOT } from '@/shared/constants/common'; import { UserFavorite } from '@/entities/user/model/types'; import { useStore } from '@/shared/model/store'; -import { useLocation } from 'react-router'; import { useTranslation } from 'react-i18next'; /* diff --git a/src/entities/menu/ui/menu-category.tsx b/src/entities/menu/ui/menu-category.tsx index 988723b..51136fc 100644 --- a/src/entities/menu/ui/menu-category.tsx +++ b/src/entities/menu/ui/menu-category.tsx @@ -1,9 +1,7 @@ import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useStore } from '@/shared/model/store'; -import { IMAGE_ROOT } from '@/shared/constants/common'; import { UserFavorite } from '@/entities/user/model/types'; import { RefObject, useEffect, useState } from 'react'; -import { useLocation } from 'react-router'; import { MenuItem } from '../model/types'; import { useTranslation } from 'react-i18next'; import { MenuItems } from '@/entities/common/model/constant'; @@ -35,8 +33,7 @@ export const MenuCategory = ({ }: MenuCategoryProps) => { const { navigate } = useNavigate(); const { i18n } = useTranslation(); - // const location = useLocation(); - + const [favoriteItems, setFavoriteItems] = useState>([]); const [menuIds, setMenuIds] = useState>([]); @@ -85,9 +82,7 @@ export const MenuCategory = ({ useStore.getState().UserStore.setUserFavorite(userFavorite); setChangeMenuId(`${menuId}-${checked}`); callFavoiteItems(); - // if(location.pathname === PATHS.home){ - - // } + }; const callFavoiteItems = () => { diff --git a/src/shared/configs/axios/index.ts b/src/shared/configs/axios/index.ts index 8a0e63a..4a07f50 100644 --- a/src/shared/configs/axios/index.ts +++ b/src/shared/configs/axios/index.ts @@ -6,7 +6,6 @@ import { getLocalStorage, setLocalStorage } from '@/shared/lib'; -import { finalizeConfig } from './utils'; import { appBridge } from '@/utils/appBridge'; import { LoginResponse } from '@/entities/user/model/types'; import { getHeaderUserAgent } from '@/shared/constants/url'; @@ -14,7 +13,16 @@ import { useAppBridge } from '@/hooks'; import { useUserInfo } from '@/entities/user/lib/use-user-info'; import { useStore } from '@/shared/model/store'; import { login } from '@/entities/user/api/use-login-mutation'; -import { useNavigate } from 'react-router'; +import { useNavigate } from '@/shared/lib/hooks'; + +const finalizeConfig = (config: InternalAxiosRequestConfig) => { + const { params, data } = config; + return { + ...config, + params, + data, + }; +}; const onRequestFulfilled = (config: InternalAxiosRequestConfig) => { config.headers['Content-Type'] = 'application/json;charset=UTF-8'; @@ -37,6 +45,7 @@ const onRequestFulfilled = (config: InternalAxiosRequestConfig) => { }; const onRequestRejected = (error: any) => { + console.log('onRequestRejected --> ', error); return Promise.reject(error); }; @@ -47,14 +56,11 @@ const onResponseFulfilled = (response: AxiosResponse) => { }; }; -export const onResponseRejected = (error: AxiosError) => { - +const onResponseRejected = (error: AxiosError) => { console.log('onResponseRejected --> ', error); - console.log('error?.status -> ', error?.status, error?.status === 401) - if(error?.status === 401){ if(appBridge.isNativeEnvironment()){ - appBridge.safeCall(() => appBridge.requestRefreshToken()).then((token: LoginResponse) => { + return appBridge.safeCall(() => appBridge.requestRefreshToken()).then((token: LoginResponse) => { setLocalStorage(StorageKeys.TokenType, token.tokenType); setLocalStorage(StorageKeys.AccessToken, token.accessToken); setLocalStorage(StorageKeys.RefreshToken, token.refreshToken); @@ -81,9 +87,7 @@ export const onResponseRejected = (error: AxiosError) => { id: 'woowahan5', password: 'nictest00' }; - login(params).then((result: LoginResponse) => { - result.usrid = params.id; - + return login(params).then((result: LoginResponse) => { setLocalStorage(StorageKeys.TokenType, result.tokenType); setLocalStorage(StorageKeys.AccessToken, result.accessToken); setLocalStorage(StorageKeys.RefreshToken, result.refreshToken); @@ -92,7 +96,7 @@ export const onResponseRejected = (error: AxiosError) => { setLocalStorage(StorageKeys.MenuGrants, result.menuGrants); setLocalStorage(StorageKeys.ClientAddressIP, result.clientAddressIP); setLocalStorage(StorageKeys.Requires2FA, result.requires2FA); - setLocalStorage(StorageKeys.Usrid, result.usrid); + setLocalStorage(StorageKeys.Usrid, params.id); if(appBridge.isNativeEnvironment()){ setLocalStorage(StorageKeys.DeviceId, result.deviceId); @@ -102,12 +106,13 @@ export const onResponseRejected = (error: AxiosError) => { useStore.getState().UserStore.setUserInfo({ ...result }); - location.reload(); + return error.config? axios.request(error.config): null; }); } } + return new Promise((_resolve, reject) => { if(checkIsAxiosError(error)){ // iOS의 경우 window에서 unload event가 일어날때 네트워크 에러가 발생하곤 해서 이런 케이스를 방지하기 위해 지연시킴 diff --git a/src/shared/configs/axios/utils.ts b/src/shared/configs/axios/utils.ts deleted file mode 100644 index e97fcbf..0000000 --- a/src/shared/configs/axios/utils.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { InternalAxiosRequestConfig } from 'axios'; - -export const finalizeConfig = (config: InternalAxiosRequestConfig) => { - const { params, data } = config; - return { - ...config, - params, - data, - }; -}; \ No newline at end of file diff --git a/src/shared/configs/query.ts b/src/shared/configs/query.ts index 65d2f8e..5a2d723 100644 --- a/src/shared/configs/query.ts +++ b/src/shared/configs/query.ts @@ -9,6 +9,7 @@ const globalQueryClient = new QueryClient({ throwOnError: true, // suspense: true, networkMode: 'always', + }, mutations: { throwOnError: true, diff --git a/src/widgets/error-boundaries/common-error-boundary.tsx b/src/widgets/error-boundaries/common-error-boundary.tsx index 5b73b86..efc6208 100644 --- a/src/widgets/error-boundaries/common-error-boundary.tsx +++ b/src/widgets/error-boundaries/common-error-boundary.tsx @@ -11,8 +11,9 @@ export const CommonErrorBoundary = (props: Props) => { const { reset } = useQueryErrorResetBoundary(); return ( - - {children} - + { children } ); }; diff --git a/src/widgets/error-boundaries/global-api-error-boundary.tsx b/src/widgets/error-boundaries/global-api-error-boundary.tsx index f9d2590..097623b 100644 --- a/src/widgets/error-boundaries/global-api-error-boundary.tsx +++ b/src/widgets/error-boundaries/global-api-error-boundary.tsx @@ -2,7 +2,6 @@ import { useQueryErrorResetBoundary } from '@tanstack/react-query'; import { PropsWithChildren } from 'react'; import { ErrorBoundary, FallbackProps } from 'react-error-boundary'; import { useLocation } from 'react-router-dom'; - import { APIError } from '@/widgets/fallbacks/api-error'; import { KickOutError } from '@/widgets/fallbacks/kick-out-error'; import { checkIsAxiosError, checkIsKickOutError } from '@/shared/lib/error'; @@ -15,17 +14,26 @@ import { checkIsAxiosError, checkIsKickOutError } from '@/shared/lib/error'; * - network * - common */ -function FallbackComponent({ error, resetErrorBoundary }: FallbackProps) { +function FallbackComponent({ + error, + resetErrorBoundary +}: FallbackProps) { // api 에러가 아닌 경우 상위 에러 바운더리로 위임 - if (!checkIsAxiosError(error)) { + if(!checkIsAxiosError(error)){ throw error; } - if (checkIsKickOutError(error)) { - return ; - } - - return ; + if(checkIsKickOutError(error)){ + return ( + + ); + } + return ( + + ); } type Props = PropsWithChildren; @@ -34,8 +42,10 @@ export const GlobalAPIErrorBoundary = ({ children }: Props) => { const { reset } = useQueryErrorResetBoundary(); const { key } = useLocation(); return ( - - {children} - + { children } ); }; diff --git a/src/widgets/error-boundaries/global-error-boundary.tsx b/src/widgets/error-boundaries/global-error-boundary.tsx index 4cbcc83..5073260 100644 --- a/src/widgets/error-boundaries/global-error-boundary.tsx +++ b/src/widgets/error-boundaries/global-error-boundary.tsx @@ -6,5 +6,7 @@ import { CommonError } from '@/widgets/fallbacks/common-error'; type Props = PropsWithChildren; export const GlobalErrorBoundary = ({ children }: Props) => { - return {children}; + return ( + { children } + ); }; diff --git a/src/widgets/fallbacks/api-error.tsx b/src/widgets/fallbacks/api-error.tsx index 8be0786..45a4d6d 100644 --- a/src/widgets/fallbacks/api-error.tsx +++ b/src/widgets/fallbacks/api-error.tsx @@ -7,14 +7,19 @@ import { Dialog, DialogProps } from '@/shared/ui/dialogs/dialog'; type CommonErrorProps = FallbackProps & { height?: number; }; -export const APIError = ({ error, resetErrorBoundary }: CommonErrorProps) => { +export const APIError = ({ + error, + resetErrorBoundary +}: CommonErrorProps) => { + console.log('APIError --> ', error); + const { navigateBack } = useNavigate(); const msg = useMemo(() => { let message: Partial = { title: '일시적인 오류가 발생하였습니다.', message: '잠시 후 다시 시도해주세요.', }; - if (error?.response?.data?.message) { + if(error?.response?.data?.message){ message = { message: error.response.data.message }; } return message; @@ -27,13 +32,13 @@ export const APIError = ({ error, resetErrorBoundary }: CommonErrorProps) => { return ( null} - open={true} - onClose={() => null} + afterLeave={ () => null } + open={ true } + onClose={ () => null } onConfirmClick={ resetErrorBoundary } onCancelClick={ handleCancel } - message={msg.message} - buttonLabel={['취소', '재시도']} + message={ msg.message } + buttonLabel={ ['취소', '재시도'] } /> ); }; diff --git a/src/widgets/fallbacks/common-error.tsx b/src/widgets/fallbacks/common-error.tsx index a81309f..42e98de 100644 --- a/src/widgets/fallbacks/common-error.tsx +++ b/src/widgets/fallbacks/common-error.tsx @@ -6,30 +6,35 @@ import { Dialog, DialogProps } from '@/shared/ui/dialogs/dialog'; type CommonErrorProps = FallbackProps & { height?: number; }; -export const CommonError = ({ error, resetErrorBoundary }: CommonErrorProps) => { +export const CommonError = ({ + error, + resetErrorBoundary +}: CommonErrorProps) => { + console.log('CommonError --> ', error); + const [isOpen, setIsOpen] = useState(true); const msg = useMemo(() => { let message: Partial = { title: '일시적인 오류가 발생하였습니다.', - message: '잠시 후 다시 시도해주세요.', + message: '잠시 후 다시 시도해주세요.' }; - if (error?.response?.data?.message) { + if(error?.response?.data?.message){ message = { message: error.response.data.message }; } - return message; + return message; }, [error]); return ( null} - open={isOpen} - onClose={() => setIsOpen(false)} - onConfirmClick={resetErrorBoundary} + afterLeave={ () => null } + open={ isOpen } + onClose={ () => setIsOpen(false) } + onConfirmClick={ resetErrorBoundary } onCancelClick={() => { location.href = '/'; }} - message={msg.message} - buttonLabel={['취소', '재시도']} + message={ msg.message } + buttonLabel={ ['취소', '재시도'] } /> ); }; diff --git a/src/widgets/fallbacks/kick-out-error.tsx b/src/widgets/fallbacks/kick-out-error.tsx index e7e2ac2..adf9d62 100644 --- a/src/widgets/fallbacks/kick-out-error.tsx +++ b/src/widgets/fallbacks/kick-out-error.tsx @@ -3,7 +3,10 @@ import { useEffect, useMemo } from 'react'; import { NiceAxiosFallbackProps } from '@/shared/@types/error'; import { Dialog, DialogProps } from '@/shared/ui/dialogs/dialog'; -export const KickOutError = ({ error, resetErrorBoundary }: NiceAxiosFallbackProps) => { +export const KickOutError = ({ + error, + resetErrorBoundary +}: NiceAxiosFallbackProps) => { useEffect(() => { console.error('[ErrorBoundary] Kickout Error', JSON.stringify(error.response?.data)); // clearAuthData(); @@ -14,8 +17,10 @@ export const KickOutError = ({ error, resetErrorBoundary }: NiceAxiosFallbackPro title: '일시적인 오류가 발생하였습니다.', message: '잠시 후 다시 시도해주세요.', }; - if (error?.response?.data?.message) { - message = { message: error.response.data.message }; + if(error?.response?.data?.message){ + message = { + message: error.response.data.message + }; } return message; }, [error]); @@ -23,7 +28,7 @@ export const KickOutError = ({ error, resetErrorBoundary }: NiceAxiosFallbackPro const handleCancel = () => { resetErrorBoundary?.(); }; - + const handleConfirm = () => { resetErrorBoundary?.(); // kickOut(); @@ -31,12 +36,13 @@ export const KickOutError = ({ error, resetErrorBoundary }: NiceAxiosFallbackPro return ( null} - open={true} - onClose={() => null} - onConfirmClick={handleConfirm} - onCancelClick={handleCancel} - message={msg.message} + afterLeave={ () => null } + open={ true } + onClose={ () => null } + onConfirmClick={ handleConfirm } + onCancelClick={ handleCancel } + message={ msg.message } + buttonLabel={ ['취소', '재시도'] } /> ); }; diff --git a/src/widgets/loadable/index.tsx b/src/widgets/loadable/index.tsx deleted file mode 100644 index b534e91..0000000 --- a/src/widgets/loadable/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Suspense } from 'react'; - -import { Loading } from '@/widgets/loading/loading'; - -export const Loadable = (Component: React.ComponentType) => { - const LoadableComponent = (props: any) => { - return ( - }> - - - ); - }; - - LoadableComponent.displayName = `Loadable(${Component.displayName || Component.name || 'Component'})`; - - return LoadableComponent; -};