13404089107
2026-04-20 03ea6417827d2dab4f7dd33626d084ff28a3de19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 * @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 router from '@/router'
 
// 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
  msg?: string
  data?: any
  success?: boolean
  total?: number
  more?: boolean
}
 
// 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
 
  // 处理401/403错误(如果不是在handleAlovaResponse中处理的)
  if ((statusCode === 401 || statusCode === 403)) {
    // 如果是未授权错误,清除用户信息并跳转到登录页
    globalToast.error({ msg: '登录已过期,请重新登录!', duration: 500 })
    const timer = setTimeout(() => {
      clearTimeout(timer)
      router.replaceAll({ name: 'login' })
    }, 500)
 
    throw new ApiError('登录已过期,请重新登录!', 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)
  }
 
  // 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)
  }
 
  // 处理401/403错误(如果不是在handleAlovaResponse中处理的)
  if (error instanceof ApiError && (error.code === 401 || error.code === 403)) {
    // 如果是未授权错误,清除用户信息并跳转到登录页
    globalToast.error({ msg: '登录已过期,请重新登录!', duration: 500 })
    const timer = setTimeout(() => {
      clearTimeout(timer)
      router.replaceAll({ name: 'login' })
    }, 500)
    throw new ApiError('登录已过期,请重新登录!', error.code, error.data)
  }
 
  // 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
}