2025-11-22 17:56:24 +08:00

101 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* API 工具函数
*
* 统一处理 API 请求和错误响应
* 提供类型安全的API请求封装
* 包括:错误响应解析、成功响应解析、统一请求函数、错误消息获取
*
* @created 2025-01-XX(从各组件提取)
* @utils
*/
import type { ApiErrorResponse, ApiSuccessResponse } from '../_components/types'
/**
* 安全地解析 API 错误响应
* @param response - fetch Response 对象
* @returns Promise<ApiErrorResponse>
*/
export async function parseErrorResponse(response: Response): Promise<ApiErrorResponse> {
try {
const data = await response.json()
return (data as ApiErrorResponse) || { error: '请求失败' }
} catch {
// 如果响应不是 JSON,返回默认错误
return { error: `HTTP ${response.status}: ${response.statusText || '请求失败'}` }
}
}
/**
* 安全地解析 API 成功响应
* @param response - fetch Response 对象
* @returns Promise<T>
*/
export async function parseSuccessResponse<T = unknown>(response: Response): Promise<T> {
const data = await response.json()
return data as T
}
/**
* 统一的 API 请求函数,自动处理错误
* @param url - API 端点
* @param options - fetch 选项
* @returns Promise<{ success: true; data: T } | { success: false; error: string }>
*/
export async function apiRequest<T = unknown>(
url: string,
options?: RequestInit
): Promise<{ success: true; data: T } | { success: false; error: string }> {
try {
const response = await fetch(url, options)
if (!response.ok) {
const errorData = await parseErrorResponse(response)
return {
success: false,
error: errorData.error || `HTTP ${response.status}: ${response.statusText || '请求失败'}`,
}
}
const data = await parseSuccessResponse<T>(response)
return {
success: true,
data,
}
} catch (error) {
console.error('API request error:', error)
const errorMessage = error instanceof Error ? error.message : '网络请求失败,请稍后重试'
return {
success: false,
error: errorMessage,
}
}
}
/**
* 获取错误消息的辅助函数
* @param error - 错误对象或错误响应
* @param defaultMessage - 默认错误消息
* @returns 错误消息字符串
*/
export function getErrorMessage(
error: unknown,
defaultMessage: string = '操作失败'
): string {
if (typeof error === 'string') {
return error
}
if (error instanceof Error) {
return error.message || defaultMessage
}
if (error && typeof error === 'object' && 'error' in error) {
const apiError = error as ApiErrorResponse
return apiError.error || defaultMessage
}
return defaultMessage
}