[UI 개선] API 테스트 페이지의 자동 및 직접 에러 처리 테스트 섹션 업데이트, 예제 소스 코드 수정 및 추가 API 테스트 기능 개선

This commit is contained in:
2025-09-22 13:16:16 +09:00
parent 221e250814
commit 75e9831907
2 changed files with 232 additions and 223 deletions

View File

@@ -11,222 +11,234 @@
</p> </p>
</div> </div>
<!-- API 테스트 섹션 --> <!-- API 테스트 섹션 -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-8"> <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-8">
<!-- 좌측: 자동 에러 처리 테스트 --> <!-- 좌측: 자동 에러 처리 테스트 -->
<div class="lg:col-span-2 space-y-6"> <div class="lg:col-span-2 space-y-6">
<!-- 자동 에러 처리 테스트 --> <!-- 자동 에러 처리 테스트 -->
<div class="bg-white rounded-lg shadow-md p-6"> <div class="bg-white rounded-lg shadow-md p-6">
<div class="flex items-center mb-4"> <div class="flex items-center mb-4">
<div <div
class="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center mr-3" class="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center mr-3"
> >
<span class="text-white font-bold text-sm">1</span> <span class="text-white font-bold text-sm">1</span>
</div> </div>
<h3 class="text-xl font-semibold text-gray-900"> <h3 class="text-xl font-semibold text-gray-900">
자동 에러 처리 테스트 자동 에러 처리 테스트
</h3> </h3>
</div> </div>
<p class="text-gray-600 mb-4"> <p class="text-gray-600 mb-4">
useApi 함수의 자동 에러 처리 기능을 테스트합니다. 에러가 발생하면 useApi 함수의 자동 에러 처리 기능을 테스트합니다. 에러가 발생하면
자동으로 alert가 표시됩니다. 자동으로 alert가 표시됩니다.
</p> </p>
<div class="space-y-3"> <div class="space-y-3">
<button <button
class="w-full bg-blue-500 hover:bg-blue-600 disabled:bg-gray-400 text-white font-medium py-3 px-4 rounded-lg transition-colors" class="w-full bg-blue-500 hover:bg-blue-600 disabled:bg-gray-400 text-white font-medium py-3 px-4 rounded-lg transition-colors"
:disabled="isLoading" :disabled="isLoading"
@click="apiTest" @click="apiTest"
> >
{{ isLoading ? "테스트 중..." : "자동 에러 처리 테스트" }} {{ isLoading ? "테스트 중..." : "자동 에러 처리 테스트" }}
</button> </button>
<div <div
v-if="autoErrorResult" v-if="autoErrorResult"
class="mt-3 p-3 bg-gray-50 rounded border" class="mt-3 p-3 bg-gray-50 rounded border"
> >
<h4 class="font-medium text-gray-900 mb-2">결과:</h4> <h4 class="font-medium text-gray-900 mb-2">결과:</h4>
<pre class="text-sm text-gray-700 whitespace-pre-wrap">{{ <pre class="text-sm text-gray-700 whitespace-pre-wrap">{{
autoErrorResult autoErrorResult
}}</pre> }}</pre>
</div> </div>
</div> </div>
<!-- 예제 소스 --> <!-- 예제 소스 -->
<div class="mt-4 p-3 bg-blue-50 rounded border"> <div class="mt-4 p-3 bg-blue-50 rounded border">
<h5 class="font-medium text-blue-900 mb-2">예제 소스:</h5> <h5 class="font-medium text-blue-900 mb-2">예제 소스:</h5>
<pre class="text-xs text-blue-800 whitespace-pre-wrap">{`// 자동 에러 처리 예제 <pre class="text-xs text-blue-800 whitespace-pre-wrap">
const apiTest = async () => { {`// 자동 에러 처리 예제
const response = await useApi<ApiResponse<Object>>( const apiTest = async () => {
"/admin/common-codes/USER_STATUS_ACTIVE222" const response = await useApi&lt;ApiResponse&lt;object&gt;&gt;(
); "/admin/common-codes/USER_STATUS_ACTIVE222"
);
if (response) {
console.log("response:", response); if (response) {
} console.log("response:", response);
};`}</apiresponse<object></pre> }
</div> };`}
</div> </pre>
</div>
</div>
<!-- 직접 에러 처리 테스트 --> <!-- 직접 에러 처리 테스트 -->
<div class="bg-white rounded-lg shadow-md p-6"> <div class="bg-white rounded-lg shadow-md p-6">
<div class="flex items-center mb-4"> <div class="flex items-center mb-4">
<div <div
class="w-10 h-10 bg-green-500 rounded-full flex items-center justify-center mr-3" class="w-10 h-10 bg-green-500 rounded-full flex items-center justify-center mr-3"
> >
<span class="text-white font-bold text-sm">2</span> <span class="text-white font-bold text-sm">2</span>
</div> </div>
<h3 class="text-xl font-semibold text-gray-900"> <h3 class="text-xl font-semibold text-gray-900">
직접 에러 처리 테스트 직접 에러 처리 테스트
</h3> </h3>
</div> </div>
<p class="text-gray-600 mb-4"> <p class="text-gray-600 mb-4">
useApi 함수의 직접 에러 처리 기능을 테스트합니다. 에러 타입에 따른 useApi 함수의 직접 에러 처리 기능을 테스트합니다. 에러 타입에 따른
세밀한 처리를 확인할 있습니다. 세밀한 처리를 확인할 있습니다.
</p> </p>
<div class="space-y-3"> <div class="space-y-3">
<button <button
class="w-full bg-green-500 hover:bg-green-600 disabled:bg-gray-400 text-white font-medium py-3 px-4 rounded-lg transition-colors" class="w-full bg-green-500 hover:bg-green-600 disabled:bg-gray-400 text-white font-medium py-3 px-4 rounded-lg transition-colors"
:disabled="isLoadingCustom" :disabled="isLoadingCustom"
@click="apiTestWithCustomError" @click="apiTestWithCustomError"
> >
{{ isLoadingCustom ? "테스트 중..." : "직접 에러 처리 테스트" }} {{ isLoadingCustom ? "테스트 중..." : "직접 에러 처리 테스트" }}
</button> </button>
<div <div
v-if="customErrorResult" v-if="customErrorResult"
class="mt-3 p-3 bg-gray-50 rounded border" class="mt-3 p-3 bg-gray-50 rounded border"
> >
<h4 class="font-medium text-gray-900 mb-2">결과:</h4> <h4 class="font-medium text-gray-900 mb-2">결과:</h4>
<pre class="text-sm text-gray-700 whitespace-pre-wrap">{{ <pre class="text-sm text-gray-700 whitespace-pre-wrap">{{
customErrorResult customErrorResult
}}</pre> }}</pre>
</div> </div>
</div> </div>
<!-- 예제 소스 --> <!-- 예제 소스 -->
<div class="mt-4 p-3 bg-green-50 rounded border"> <div class="mt-4 p-3 bg-green-50 rounded border">
<h5 class="font-medium text-green-900 mb-2">예제 소스:</h5> <h5 class="font-medium text-green-900 mb-2">예제 소스:</h5>
<pre class="text-xs text-green-800 whitespace-pre-wrap">{`// 직접 에러 처리 예제 <pre class="text-xs text-green-800 whitespace-pre-wrap">
const apiTestWithCustomError = async () => { {`// 직접 에러 처리 예제
try { const apiTestWithCustomError = async () => {
const response = await useApi<ApiResponse<Object>>( try {
"/admin/common-codes/USER_STATUS_ACTIVE222", const response = await useApi&lt;ApiResponse&lt;object&gt;&gt;(
{ "/admin/common-codes/USER_STATUS_ACTIVE222",
handleError: false, // 에러를 직접 처리 {
showAlert: false, // alert 표시 안함 handleError: false, // 에러를 직접 처리
} showAlert: false, // alert 표시 안함
); }
);
if (response) {
console.log("response:", response); if (response) {
} console.log("response:", response);
} catch (error: any) { }
// 에러 타입에 따른 세밀한 처리 } catch (error: any) {
if (error.response?.status === 404) { // 에러 타입에 따른 세밀한 처리
alert("요청한 코드를 찾을 수 없습니다."); if (error.response?.status === 404) {
} else if (error.response?.status === 403) { alert("요청한 코드를 찾을 수 없습니다.");
alert("접근 권한이 없습니다."); } else if (error.response?.status === 403) {
} else if (error.response?.status >= 500) { alert("접근 권한이 없습니다.");
alert("서버 오류가 발생했습니다."); } else if (error.response?.status >= 500) {
} else { alert("서버 오류가 발생했습니다.");
alert("알 수 없는 오류가 발생했습니다."); } else {
} alert("알 수 없는 오류가 발생했습니다.");
} }
};`}</apiresponse<object></pre> }
</div> };`}
</div> </pre>
</div> </div>
</div>
</div>
<!-- 우측: 추가 API 테스트 --> <!-- 우측: 추가 API 테스트 -->
<div class="lg:col-span-1"> <div class="lg:col-span-1">
<div class="bg-white rounded-lg shadow-md p-6"> <div class="bg-white rounded-lg shadow-md p-6">
<div class="flex items-center mb-4"> <div class="flex items-center mb-4">
<div <div
class="w-10 h-10 bg-purple-500 rounded-full flex items-center justify-center mr-3" class="w-10 h-10 bg-purple-500 rounded-full flex items-center justify-center mr-3"
> >
<span class="text-white font-bold text-sm">3</span> <span class="text-white font-bold text-sm">3</span>
</div> </div>
<h3 class="text-xl font-semibold text-gray-900">추가 API 테스트</h3> <h3 class="text-xl font-semibold text-gray-900">
</div> 추가 API 테스트
<p class="text-gray-600 mb-4"> </h3>
다양한 API 엔드포인트를 테스트할 있습니다. </div>
</p> <p class="text-gray-600 mb-4">
다양한 API 엔드포인트를 테스트할 있습니다.
</p>
<div class="space-y-3"> <div class="space-y-3">
<button <button
class="w-full bg-purple-500 hover:bg-purple-600 disabled:bg-gray-400 text-white font-medium py-2 px-4 rounded-lg transition-colors" class="w-full bg-purple-500 hover:bg-purple-600 disabled:bg-gray-400 text-white font-medium py-2 px-4 rounded-lg transition-colors"
:disabled="isLoadingValid" :disabled="isLoadingValid"
@click="testValidEndpoint" @click="testValidEndpoint"
> >
{{ isLoadingValid ? "테스트 중..." : "유효한 엔드포인트" }} {{ isLoadingValid ? "테스트 중..." : "유효한 엔드포인트" }}
</button> </button>
<button <button
class="w-full bg-red-500 hover:bg-red-600 disabled:bg-gray-400 text-white font-medium py-2 px-4 rounded-lg transition-colors" class="w-full bg-red-500 hover:bg-red-600 disabled:bg-gray-400 text-white font-medium py-2 px-4 rounded-lg transition-colors"
:disabled="isLoadingNetwork" :disabled="isLoadingNetwork"
@click="testNetworkError" @click="testNetworkError"
> >
{{ isLoadingNetwork ? "테스트 중..." : "네트워크 에러" }} {{ isLoadingNetwork ? "테스트 중..." : "네트워크 에러" }}
</button> </button>
<button <button
class="w-full bg-gray-500 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors" class="w-full bg-gray-500 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors"
@click="clearResults" @click="clearResults"
> >
결과 초기화 결과 초기화
</button> </button>
</div> </div>
<div v-if="additionalResults.length > 0" class="mt-4 space-y-3"> <div v-if="additionalResults.length > 0" class="mt-4 space-y-3">
<h4 class="font-medium text-gray-900">추가 테스트 결과:</h4> <h4 class="font-medium text-gray-900">추가 테스트 결과:</h4>
<div <div
v-for="(result, index) in additionalResults" v-for="(result, index) in additionalResults"
:key="index" :key="index"
class="p-3 bg-gray-50 rounded border" class="p-3 bg-gray-50 rounded border"
> >
<div class="flex justify-between items-center mb-2"> <div class="flex justify-between items-center mb-2">
<span class="font-medium text-gray-900 text-sm">{{ result.title }}</span> <span class="font-medium text-gray-900 text-sm">{{
<span class="text-xs text-gray-500">{{ result.timestamp }}</span> result.title
</div> }}</span>
<pre class="text-xs text-gray-700 whitespace-pre-wrap">{{ <span class="text-xs text-gray-500">{{
result.data result.timestamp
}}</pre> }}</span>
</div> </div>
</div> <pre class="text-xs text-gray-700 whitespace-pre-wrap">{{
result.data
<!-- 예제 소스 --> }}</pre>
<div class="mt-4 p-3 bg-purple-50 rounded border"> </div>
<h5 class="font-medium text-purple-900 mb-2">예제 소스:</h5> </div>
<pre class="text-xs text-purple-800 whitespace-pre-wrap">{`// 추가 API 테스트 예제
const testValidEndpoint = async () => {
try {
const response = await useApi<ApiResponse<Object>>(
"/admin/common-codes/USER_STATUS_ACTIVE",
{
handleError: false,
showAlert: false,
}
);
console.log("성공:", response);
} catch (error: any) {
console.log("에러:", error.message);
}
};
const testNetworkError = async () => { <!-- 예제 소스 -->
try { <div class="mt-4 p-3 bg-purple-50 rounded border">
const response = await useApi<ApiResponse<Object>>( <h5 class="font-medium text-purple-900 mb-2">예제 소스:</h5>
"/non-existent-endpoint", <pre class="text-xs text-purple-800 whitespace-pre-wrap">
{ {`// 추가 API 테스트 예제
handleError: false, const testValidEndpoint = async () => {
showAlert: false, try {
} const response = await useApi&lt;ApiResponse&lt;object&gt;&gt;(
); "/admin/common-codes/USER_STATUS_ACTIVE",
} catch (error: any) { {
console.log("네트워크 에러:", error.message); handleError: false,
} showAlert: false,
};`}</apiresponse<object></apiresponse<object></pre> }
</div> );
</div>
</div> console.log("성공:", response);
</div> } catch (error: any) {
console.log("에러:", error.message);
}
};
const testNetworkError = async () => {
try {
const response = await useApi&lt;ApiResponse&lt;object&gt;&gt;(
"/non-existent-endpoint",
{
handleError: false,
showAlert: false,
}
);
} catch (error: any) {
console.log("네트워크 에러:", error.message);
}
};`}
</pre>
</div>
</div>
</div>
</div>
<!-- 사용법 가이드 --> <!-- 사용법 가이드 -->
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-6"> <div class="bg-yellow-50 border border-yellow-200 rounded-lg p-6">
@@ -279,21 +291,17 @@ const apiTest = async () => {
isLoading.value = true; isLoading.value = true;
autoErrorResult.value = ""; autoErrorResult.value = "";
try { const response = await useApi<ApiResponse<object>>(
const response = await useApi<ApiResponse<object>>( "/admin/common-codes/USER_STATUS_ACTIVE222"
"/admin/common-codes/USER_STATUS_ACTIVE222" );
);
if (response) { if (response) {
autoErrorResult.value = `성공: ${JSON.stringify(response, null, 2)}`; autoErrorResult.value = `성공: ${JSON.stringify(response, null, 2)}`;
} else { } else {
autoErrorResult.value = "응답이 없습니다."; autoErrorResult.value = "응답이 없습니다.";
}
} catch (error: any) {
autoErrorResult.value = `에러 발생: ${error.message || "알 수 없는 에러"}`;
} finally {
isLoading.value = false;
} }
isLoading.value = false;
}; };
// 직접 에러 처리하는 함수 예시 // 직접 에러 처리하는 함수 예시
@@ -316,7 +324,7 @@ const apiTestWithCustomError = async () => {
customErrorResult.value = "응답이 없습니다."; customErrorResult.value = "응답이 없습니다.";
} }
} catch (error: any) { } catch (error: any) {
// 에러 타입에 따른 세밀한 처리 // 에러 타입에 처리
let errorMessage = ""; let errorMessage = "";
if (error.response?.status === 404) { if (error.response?.status === 404) {
errorMessage = "[errorCustomHandler]요청한 코드를 찾을 수 없습니다."; errorMessage = "[errorCustomHandler]요청한 코드를 찾을 수 없습니다.";

View File

@@ -14,6 +14,7 @@ export const useUserStore = defineStore(
interface LoginData { interface LoginData {
userId: string; userId: string;
name: string;
} }
// 액션 // 액션
const login = async (userId: string, password: string) => { const login = async (userId: string, password: string) => {