/*
|
* @Author: weisheng
|
* @Date: 2025-04-17 15:58:11
|
* @LastEditTime: 2025-06-15 21:47:22
|
* @LastEditors: weisheng
|
* @Description: Alova response and error handlers
|
* @FilePath: /wot-starter/src/api/core/handlers.ts
|
*/
|
import type { Method } from 'alova'
|
import { triggerUnauthorizedRedirect } from '@/router/authRedirect'
|
import { clearMiniAuthSession } from '@/store/auth'
|
|
// Custom error class for API errors
|
export class ApiError extends Error {
|
code: number
|
data?: any
|
|
constructor(message: string, code: number, data?: any) {
|
super(message)
|
this.name = 'ApiError'
|
this.code = code
|
this.data = data
|
}
|
}
|
|
// Define a type for the expected API response structure
|
interface ApiResponse {
|
code: number
|
message?: string
|
result?: any
|
success?: boolean
|
total?: number
|
}
|
|
let redirectingToLogin = false
|
|
function handleUnauthorized(message?: string, code = 401, data?: any) {
|
clearMiniAuthSession()
|
if (!redirectingToLogin) {
|
redirectingToLogin = true
|
const globalToast = useGlobalToast()
|
globalToast.error({ msg: message || '登录已过期,请重新登录!', duration: 1200 })
|
const timer = setTimeout(() => {
|
clearTimeout(timer)
|
redirectingToLogin = false
|
triggerUnauthorizedRedirect()
|
}, 300)
|
}
|
throw new ApiError(message || '登录已过期,请重新登录!', code, data)
|
}
|
|
// Handle successful responses
|
export async function handleAlovaResponse(
|
response: UniApp.RequestSuccessCallbackResult | UniApp.UploadFileSuccessCallbackResult | UniApp.DownloadSuccessData,
|
) {
|
const globalToast = useGlobalToast()
|
// Extract status code and data from UniApp response
|
const { statusCode, data } = response as UniNamespace.RequestSuccessCallbackResult
|
|
if (statusCode === 401 || statusCode === 403) {
|
handleUnauthorized('登录已过期,请重新登录!', statusCode, data)
|
}
|
|
// Handle HTTP error status codes
|
if (statusCode >= 400) {
|
globalToast.error(`Request failed with status: ${statusCode}`)
|
throw new ApiError(`Request failed with status: ${statusCode}`, statusCode, data)
|
}
|
|
// The data is already parsed by UniApp adapter
|
const json = data as ApiResponse
|
// Log response in development
|
if (import.meta.env.MODE === 'development') {
|
console.log('[Alova Response]', json)
|
}
|
|
if (json.code === 401 || json.code === 403) {
|
handleUnauthorized(json.message, json.code, json)
|
}
|
|
// Return data for successful responses
|
return json
|
}
|
|
// Handle request errors
|
export function handleAlovaError(error: any, method: Method) {
|
const globalToast = useGlobalToast()
|
// Log error in development
|
if (import.meta.env.MODE === 'development') {
|
console.error('[Alova Error]', error, method)
|
}
|
|
if (error instanceof ApiError && (error.code === 401 || error.code === 403)) {
|
throw error
|
}
|
|
// Handle different types of errors
|
if (error.name === 'NetworkError') {
|
globalToast.error('网络错误,请检查您的网络连接')
|
}
|
else if (error.name === 'TimeoutError') {
|
globalToast.error('请求超时,请重试')
|
}
|
else if (error instanceof ApiError) {
|
globalToast.error(error.message || '请求失败')
|
}
|
else {
|
globalToast.error('发生意外错误')
|
}
|
|
throw error
|
}
|