[UI 개선] API 테스트 페이지의 자동 및 직접 에러 처리 테스트 섹션 업데이트, 예제 소스 코드 수정 및 추가 API 테스트 기능 개선
This commit is contained in:
@@ -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<ApiResponse<object>>(
|
||||||
);
|
"/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<ApiResponse<object>>(
|
||||||
{
|
"/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<ApiResponse<object>>(
|
||||||
);
|
"/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<ApiResponse<object>>(
|
||||||
|
"/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]요청한 코드를 찾을 수 없습니다.";
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user