Skip to content

Commit

Permalink
feat: fetcher 에 에러 핸들링 로직 추가 완료
Browse files Browse the repository at this point in the history
  • Loading branch information
ooherin committed Oct 15, 2024
1 parent fe1180a commit c89936b
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 48 deletions.
1 change: 0 additions & 1 deletion frontend/src/apis/checklist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,5 @@ export const deleteChecklist = async (id: number) => {

export const putCustomChecklist = async (questionIds: ChecklistSelectedQuestions) => {
const response = await fetcher.put({ url: BASE_URL + ENDPOINT.CHECKLIST_CUSTOM, body: questionIds });

return response;
};
70 changes: 28 additions & 42 deletions frontend/src/apis/fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { API_ERROR_MESSAGE } from '@/apis/error/ErrorMessage';
import HTTPError from '@/apis/error/HttpError';
import { postReissueAccessToken } from '@/apis/user';
import { deleteToken, postReissueAccessToken } from '@/apis/user';
import { HTTP_STATUS_CODE } from '@/constants/httpErrorMessage';
import { ROUTE_PATH } from '@/constants/routePath';

let reissueAccessToken = false;
let reissueAccessTokenFailed = false;

interface RequestProps {
url: string;
Expand All @@ -17,39 +17,46 @@ interface RequestProps {
type FetchProps = Omit<RequestProps, 'method'>;

const request = async ({ url, method, body, headers = {} }: RequestProps) => {
if (reissueAccessTokenFailed) {
//TODO: 토큰 재발급 실패 후 후 요청 안보내는 로직 필요
throw new HTTPError(400, 'Access Token 재발급 실패로 인해 요청이 중단되었습니다.');
}

try {
const response = await fetchRequest({ url, method, body, headers });
if (!response.ok) {
await handleError(response, { url, method, body, headers });
}
return response;
} catch (error) {
if (error instanceof HTTPError) {
if (error.statusCode === 401 && error.message === API_ERROR_MESSAGE.REISSUE_TOKEN_NEED && !reissueAccessToken) {
reissueAccessToken = true;
const response = await postReissueAccessToken();
throw error;
} else {
throw new HTTPError(HTTP_STATUS_CODE.NETWORK_ERROR, 'Network error occurred');
}
}
};

const handleError = async (response: Response, { url, method, body, headers = {} }: RequestProps) => {
const responseString = await response.text();
const errorMessage = JSON.parse(responseString).message;

if (response.status === 200) {
if (response.status === 401 && errorMessage === API_ERROR_MESSAGE.REISSUE_TOKEN_NEED) {
if (!reissueAccessToken) {
reissueAccessToken = true;
try {
const accessTokenReissueResult = await postReissueAccessToken();
if (accessTokenReissueResult?.status === 200) {
reissueAccessToken = false;
return retryRequest({ url, method, body, headers });
return await fetchRequest({ url, method, body, headers });
}

reissueAccessTokenFailed = true;
//TODO: 로그아웃 후 이동시키는 로직 필요
//logout()
//window.location.href = ROUTE_PATH.root;
} catch (err) {
await deleteToken();
window.location.href = ROUTE_PATH.root;
}
throw error;
} else {
throw new HTTPError(HTTP_STATUS_CODE.NETWORK_ERROR, '');
}
} else {
throw new HTTPError(response.status, errorMessage);
}
};

const fetchRequest = async ({ url, method, body, headers = {}, signal }: RequestProps & { signal?: AbortSignal }) => {
const response = await fetch(url, {
return await fetch(url, {
method,
credentials: 'include',
body: body ? JSON.stringify(body) : undefined,
Expand All @@ -58,27 +65,6 @@ const fetchRequest = async ({ url, method, body, headers = {}, signal }: Request
},
signal: signal,
});

if (!response.ok) {
const responseString = await response.text();
const errorMessage = JSON.parse(responseString).message;
throw new HTTPError(response.status, errorMessage);
}

return response;
};

const retryRequest = async ({ url, method, body, headers = {}, signal }: RequestProps & { signal?: AbortSignal }) => {
try {
const response = await fetchRequest({ url, method, body, headers, signal });
return response;
} catch (error) {
if (error instanceof HTTPError) {
throw new HTTPError(error.statusCode, error.message);
} else {
throw new HTTPError(HTTP_STATUS_CODE.NETWORK_ERROR, '');
}
}
};

const fetcher = {
Expand Down
1 change: 0 additions & 1 deletion frontend/src/apis/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export const postLogout = async () => {
const response = await fetch(`${BASE_URL}${ENDPOINT.LOGOUT}`, {
method: 'POST',
});

return response;
};

Expand Down
3 changes: 1 addition & 2 deletions frontend/src/hooks/useChecklistQuestionSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ export interface UpdateCheckProps extends CategoryAndQuestion {
}

const useChecklistQuestionSelect = () => {
const { setChecklistAllQuestionList, checklistAllQuestionList, selectedQuestions } =
useChecklistQuestionSelectStore();
const { setChecklistAllQuestionList, checklistAllQuestionList } = useChecklistQuestionSelectStore();

const toggleQuestionSelect = ({ categoryId, questionId, isSelected }: UpdateCheckProps) => {
const targetCategory = checklistAllQuestionList.find(category => category.categoryId === categoryId);
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/hooks/useIsValidUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ const useIsValidUser = () => {
if (!isAccessTokenExist) {
try {
const accessTokenReissueResult = await postReissueAccessToken();
if (accessTokenReissueResult.status !== 200) return;
if (accessTokenReissueResult?.status !== 200) return;
} catch (err) {
return await deleteToken();
}
}

const result = await getUserInfo();
showToast({ message: `${result.userName}님, 환영합니다.`, type: 'confirm' });
showToast({ message: `${result?.userName}님, 환영합니다.`, type: 'confirm' });
return navigate(ROUTE_PATH.home);
}
};
Expand Down

0 comments on commit c89936b

Please sign in to comment.