-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FE] 클라이언트 영역 에러 핸들링 개선 (토스트 UI) (#419)
* feat: Context API를 사용해서 전역적으로 에러 상태를 관리할 수 있도록 개선 - 에러 상태와 에러 상태를 변경하는 컨텍스를 구분 - QueryClientManager 컴포넌트에서 mutation에서 에러가 발생하면 이를 감지해 에러 상태를 업데이트 - Context API에서 공유받는 데이터를 편하게 사용할 수 있도록, 커스텀 훅으로 useContext를 추상화 * refactor: fetchClient 함수 로직 변경, fetcher 모듈 생성 - fetchClient 함수에서 데이터를 반환하는 것이 아니라, 서버의 응답 객체를 반환하는 것으로 수정 - 예외가 발생했을 경우에는 ResponseError 객체를 생성해서 에러를 throw - get, post, postWithResponse, delete 메서드 생성 * refactor: fetcher 모듈을 사용하는 것으로 수정 * feat: 에러 상태를 구독하고 토스트 UI로 피드백을 전달하는 컴포넌트 구현 * feat: 약속을 잠그고 약속 확정하러 갈 것인지를 묻는 모달 구현 * refactor: AuthProvider 컴포넌트에서 예외적으로 useParams 훅을 사용하는 것으로 수정 - 기존 UuidContext를 사용하면 undefined로 참조되는 문제를 해결하기 위해 예외 처리 * refactor: 필요하지 않은 상태 제거 * chore: 강조 텍스트 수정
- Loading branch information
Showing
17 changed files
with
285 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import type { FetchOption } from './fetchClient'; | ||
import { fetchClient } from './fetchClient'; | ||
|
||
type FetcherArgs = Omit<FetchOption, 'method'>; | ||
|
||
export const fetcher = { | ||
get: async <T>({ path, isAuthRequire }: FetcherArgs): Promise<T> => { | ||
const response = await fetchClient({ | ||
path, | ||
method: 'GET', | ||
isAuthRequire, | ||
}); | ||
|
||
const data = await response.json(); | ||
|
||
return data.data as T; | ||
}, | ||
post: async ({ path, body, isAuthRequire = false }: FetcherArgs) => { | ||
await fetchClient({ path, method: 'POST', body, isAuthRequire }); | ||
}, | ||
postWithResponse: async <T>({ path, body, isAuthRequire = false }: FetcherArgs): Promise<T> => { | ||
const response = await fetchClient({ path, method: 'POST', body, isAuthRequire }); | ||
|
||
const data = await response.json(); | ||
|
||
return data.data as T; | ||
}, | ||
delete: async ({ path, isAuthRequire = false }: FetcherArgs) => { | ||
await fetchClient({ path, method: 'DELETE', isAuthRequire }); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { PropsWithChildren } from 'react'; | ||
import { useEffect, useRef } from 'react'; | ||
|
||
import useErrorState from '@hooks/useErrorState/useErrorState'; | ||
import useToast from '@hooks/useToast/useToast'; | ||
|
||
export default function ErrorToastNotifier({ children }: PropsWithChildren) { | ||
const error = useErrorState(); | ||
const { addToast } = useToast(); | ||
|
||
const addToastCallbackRef = useRef< | ||
(({ type, message, duration }: Parameters<typeof addToast>[0]) => void) | null | ||
>(null); | ||
addToastCallbackRef.current = addToast; | ||
|
||
useEffect(() => { | ||
if (!error || !addToastCallbackRef.current) return; | ||
|
||
addToastCallbackRef.current({ type: 'warning', message: error.message, duration: 3000 }); | ||
}, [error]); | ||
|
||
return children; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; | ||
import { type PropsWithChildren } from 'react'; | ||
|
||
import useErrorDispatch from '@hooks/useErrorDispatch/useErrorDispatch'; | ||
|
||
import { ResponseError } from '@utils/responseError'; | ||
|
||
export default function QueryClientManager({ children }: PropsWithChildren) { | ||
const setError = useErrorDispatch(); | ||
|
||
const queryClient = new QueryClient({ | ||
defaultOptions: { | ||
queries: { | ||
throwOnError: true, | ||
}, | ||
mutations: { | ||
onError: (error: unknown) => { | ||
if (error instanceof ResponseError) { | ||
setError(error); | ||
} | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>; | ||
} |
Oops, something went wrong.