[API 개선] useApi 함수에 에러 처리 옵션 추가 및 사용 예시 업데이트
This commit is contained in:
@@ -3,11 +3,11 @@
|
|||||||
*
|
*
|
||||||
* @template T - 응답 데이터의 타입
|
* @template T - 응답 데이터의 타입
|
||||||
* @param path - API 엔드포인트 경로 (예: '/users', '/users/1')
|
* @param path - API 엔드포인트 경로 (예: '/users', '/users/1')
|
||||||
* @param opts - 요청 옵션 (method, body, headers 등)
|
* @param options - 요청 및 에러 처리 옵션
|
||||||
* @returns Promise<T> - API 응답 데이터
|
* @returns Promise<T> - API 응답 데이터
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* // GET 요청
|
* // GET 요청 (기본)
|
||||||
* const users = await useApi<User[]>('/users')
|
* const users = await useApi<User[]>('/users')
|
||||||
*
|
*
|
||||||
* // POST 요청
|
* // POST 요청
|
||||||
@@ -16,21 +16,75 @@
|
|||||||
* body: { name: 'John', email: 'john@example.com' }
|
* body: { name: 'John', email: 'john@example.com' }
|
||||||
* })
|
* })
|
||||||
*
|
*
|
||||||
* // PUT 요청
|
* // 에러 시 alert 표시
|
||||||
* const updatedUser = await useApi<User>('/users/1', {
|
* const data = await useApi<User[]>('/users', { showAlert: true })
|
||||||
* method: 'PUT',
|
|
||||||
* body: { name: 'John Updated' }
|
|
||||||
* })
|
|
||||||
*
|
*
|
||||||
* // DELETE 요청
|
* // 에러를 직접 처리
|
||||||
* await useApi('/users/1', { method: 'DELETE' })
|
* try {
|
||||||
|
* const data = await useApi<User[]>('/users', { handleError: false })
|
||||||
|
* } catch (error) {
|
||||||
|
* // 직접 에러 처리
|
||||||
|
* }
|
||||||
*
|
*
|
||||||
* // FormData 업로드
|
* // FormData 업로드
|
||||||
* const formData = new FormData()
|
* const formData = new FormData()
|
||||||
* formData.append('file', file)
|
* formData.append('file', file)
|
||||||
* await useApi('/upload', { method: 'POST', body: formData })
|
* await useApi('/upload', { method: 'POST', body: formData })
|
||||||
*/
|
*/
|
||||||
export const useApi = <T>(path: string, opts?: any): Promise<T> => {
|
export const useApi = async <T>(
|
||||||
|
path: string,
|
||||||
|
options?: {
|
||||||
|
// API 요청 옵션
|
||||||
|
method?: string;
|
||||||
|
body?: any;
|
||||||
|
headers?: Record<string, string>;
|
||||||
|
// 에러 처리 옵션
|
||||||
|
handleError?: boolean; // true: 에러를 null로 반환, false: 에러를 다시 던짐
|
||||||
|
showAlert?: boolean; // true: 에러 시 alert 표시
|
||||||
|
}
|
||||||
|
): Promise<T> => {
|
||||||
const { $api } = useNuxtApp();
|
const { $api } = useNuxtApp();
|
||||||
return ($api as any)(path, opts);
|
|
||||||
|
// 기본값 설정
|
||||||
|
const {
|
||||||
|
method = "GET",
|
||||||
|
body,
|
||||||
|
headers,
|
||||||
|
handleError = true,
|
||||||
|
showAlert = true,
|
||||||
|
} = options || {};
|
||||||
|
|
||||||
|
// API 요청 옵션 구성
|
||||||
|
const apiOpts = {
|
||||||
|
method,
|
||||||
|
...(body && { body }),
|
||||||
|
...(headers && { headers }),
|
||||||
|
};
|
||||||
|
|
||||||
|
return ($api as any)(path, apiOpts).catch((error: any) => {
|
||||||
|
// 사용자에게 알림 표시
|
||||||
|
if (showAlert) {
|
||||||
|
const status = error.response?.status;
|
||||||
|
let message =
|
||||||
|
status === 404
|
||||||
|
? "요청한 리소스를 찾을 수 없습니다."
|
||||||
|
: status === 500
|
||||||
|
? "서버 오류가 발생했습니다."
|
||||||
|
: "요청 처리 중 오류가 발생했습니다.";
|
||||||
|
|
||||||
|
// 서버에서 온 에러 메시지가 있으면 우선 사용
|
||||||
|
if (error.response?._data?.description) {
|
||||||
|
message = error.response._data.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 에러 처리 방식에 따라 반환
|
||||||
|
if (handleError) {
|
||||||
|
return null as T; // 에러를 null로 반환
|
||||||
|
} else {
|
||||||
|
throw error; // 에러를 다시 던짐
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,13 +29,16 @@
|
|||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-gray-600">
|
<p class="text-sm text-gray-600">
|
||||||
<button
|
<button
|
||||||
@click="
|
class="mr-2 bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 rounded"
|
||||||
useApi<ApiResponse<{}>>('/files/download/1756167537354001', {
|
@click="apiTest"
|
||||||
method: 'get',
|
|
||||||
})
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
Test
|
자동 에러 처리
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="bg-green-500 hover:bg-green-600 text-white px-3 py-1 rounded"
|
||||||
|
@click="apiTestWithCustomError"
|
||||||
|
>
|
||||||
|
직접 에러 처리
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -119,6 +122,47 @@ definePageMeta({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
// 테스트 다운로드 함수 (자동 에러 처리)
|
||||||
|
const apiTest = async () => {
|
||||||
|
const response = await useApi<ApiResponse<object>>(
|
||||||
|
"/admin/common-codes/USER_STATUS_ACTIVE222"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
console.log("response:", response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 직접 에러 처리하는 함수 예시
|
||||||
|
const apiTestWithCustomError = async () => {
|
||||||
|
try {
|
||||||
|
const response = await useApi<ApiResponse<object>>(
|
||||||
|
"/admin/common-codes/USER_STATUS_ACTIVE222",
|
||||||
|
{
|
||||||
|
handleError: false, // 에러를 직접 처리하겠다는 의미
|
||||||
|
showAlert: false, // alert는 표시하지 않음
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
console.log("response:", response);
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
// 에러 타입에 따른 세밀한 처리
|
||||||
|
if (error.response?.status === 404) {
|
||||||
|
alert("[errorCustomHandler]요청한 코드를 찾을 수 없습니다.");
|
||||||
|
} else if (error.response?.status === 403) {
|
||||||
|
alert("[errorCustomHandler]접근 권한이 없습니다.");
|
||||||
|
} else if (error.response?.status >= 500) {
|
||||||
|
alert(
|
||||||
|
"[errorCustomHandler]서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요."
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
alert("[errorCustomHandler]알 수 없는 오류가 발생했습니다.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user