lty/qy-lty-admin/lib/api/error-handler.ts
2026-03-17 13:17:02 +08:00

145 lines
3.9 KiB
TypeScript

import type { ApiResponse } from "./client"
import { toast } from "@/components/ui/use-toast"
// 错误代码映射表
const errorMessages: Record<string, string> = {
// 用户相关错误
USER_NOT_FOUND: "用户不存在",
EMAIL_EXISTS: "该邮箱已被注册",
CANNOT_DELETE_ADMIN: "无法删除超级管理员用户",
// 角色相关错误
ROLE_NOT_FOUND: "角色不存在",
ROLE_EXISTS: "该角色名称已存在",
CANNOT_DELETE_SYSTEM_ROLE: "无法删除系统角色",
ROLE_IN_USE: "该角色正在被用户使用,无法删除",
// 服装相关错误
OUTFIT_NOT_FOUND: "服装不存在",
OUTFIT_ALREADY_PUBLISHED: "服装已发布,无法修改",
BATCH_NOT_FOUND: "批次不存在",
// 道具相关错误
PROP_NOT_FOUND: "道具不存在",
PROP_ALREADY_PUBLISHED: "道具已发布,无法修改",
// 歌曲相关错误
SONG_NOT_FOUND: "歌曲不存在",
SONG_ALREADY_PUBLISHED: "歌曲已发布,无法修改",
// 通用错误
NETWORK_ERROR: "网络错误,请检查网络连接",
SERVER_ERROR: "服务器错误,请稍后重试",
UNAUTHORIZED: "未授权,请重新登录",
FORBIDDEN: "无权限执行此操作",
}
// 处理API错误
export const handleApiError = (error: unknown): string => {
if (error instanceof Error) {
return error.message
}
return "发生未知错误,请重试"
}
// 创建API错误
export class ApiError extends Error {
status: number
constructor(message: string, status = 500) {
super(message)
this.name = "ApiError"
this.status = status
}
}
// 处理API响应
export const handleResponse = async <T>(response: Response)
: Promise<T> =>
{
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
throw new ApiError(errorData.message || `请求失败: ${response.status} ${response.statusText}`, response.status)
}
return response.json();
}
// 显示API错误提示
export function showApiError<T>(response: ApiResponse<T>, defaultMessage = "操作失败"): void {
const errorMessage = handleApiError(response, defaultMessage)
toast({
title: "错误",
description: errorMessage,
variant: "destructive",
})
}
// 处理API异常
export function handleApiException(error: unknown, defaultMessage = "操作失败"): string {
console.error("API Exception:", error)
if (error instanceof Error) {
if (error.message.includes("Network error")) {
return errorMessages["NETWORK_ERROR"]
}
return error.message
}
return defaultMessage
}
// 显示API异常提示
export function showApiException(error: unknown, defaultMessage = "操作失败"): void {
const errorMessage = handleApiException(error, defaultMessage)
toast({
title: "错误",
description: errorMessage,
variant: "destructive",
})
}
// 统一的API请求处理函数
export async function handleApiRequest<T>(
apiCall: () => Promise<ApiResponse<T>>,
options: {
successMessage?: string
errorMessage?: string
showSuccessToast?: boolean
showErrorToast?: boolean
} = {},
): Promise<{ success: boolean; data?: T; error?: string }> {
const {
successMessage = "操作成功",
errorMessage = "操作失败",
showSuccessToast = true,
showErrorToast = true,
} = options
try {
const response = await apiCall()
if (response.success) {
if (showSuccessToast) {
toast({
title: "成功",
description: successMessage,
})
}
return { success: true, data: response.data }
} else {
const error = handleApiError(response, errorMessage)
if (showErrorToast) {
showApiError(response, errorMessage)
}
return { success: false, error }
}
} catch (error) {
const errorMsg = handleApiException(error, errorMessage)
if (showErrorToast) {
showApiException(error, errorMessage)
}
return { success: false, error: errorMsg }
}
}