mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
refactor: 前端全面替换 any 为 unknown 并统一错误处理,后端用量记录补写请求头/体
- 前端 API 层、stores、conversation 解析器、组件全面替换 any 为 unknown/具体类型 - 错误处理统一使用 parseApiError/getErrorStatus 替代 err.response?.data?.detail 模式 - 后端 handler/TaskService/UsageLifecycle/StreamTracker 链路传递 request_headers/request_body - streaming/pending 状态更新时可补写客户端和提供商的请求头及请求体 - 新增 TaskService 和 UsageService 相关测试
This commit is contained in:
@@ -3,6 +3,8 @@ import { ref, computed } from 'vue'
|
||||
import { authApi, type User } from '@/api/auth'
|
||||
import apiClient from '@/api/client'
|
||||
import { log } from '@/utils/logger'
|
||||
import { parseApiError } from '@/utils/errorParser'
|
||||
import { getErrorStatus } from '@/types/api-error'
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
// 初始化时从 localStorage 恢复 token
|
||||
@@ -44,16 +46,17 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
user.value = userInfo
|
||||
|
||||
return true
|
||||
} catch (err: any) {
|
||||
} catch (err: unknown) {
|
||||
// 不要暴露后端的详细错误信息
|
||||
if (err.response?.status === 401) {
|
||||
const status = getErrorStatus(err)
|
||||
if (status === 401) {
|
||||
error.value = '邮箱或密码错误'
|
||||
} else if (err.response?.status === 422) {
|
||||
} else if (status === 422) {
|
||||
error.value = '请输入有效的邮箱地址'
|
||||
} else if (err.response?.status === 429) {
|
||||
} else if (status === 429) {
|
||||
// 限流错误,显示后端返回的具体信息
|
||||
error.value = err.response?.data?.detail || '请求过于频繁,请稍后重试'
|
||||
} else if (err.response?.status === 500) {
|
||||
error.value = parseApiError(err, '请求过于频繁,请稍后重试')
|
||||
} else if (status === 500) {
|
||||
error.value = '服务器错误,请稍后重试'
|
||||
} else {
|
||||
error.value = '登录失败,请检查网络连接'
|
||||
@@ -75,7 +78,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
const userInfo = await authApi.getCurrentUser()
|
||||
user.value = userInfo
|
||||
return userInfo
|
||||
} catch (err: any) {
|
||||
} catch (err: unknown) {
|
||||
log.error('Failed to fetch user info', err)
|
||||
// 根据用户要求,不管什么错误都不清除状态
|
||||
// 保持登录状态,除非用户手动退出
|
||||
|
||||
@@ -2,6 +2,7 @@ import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { modulesApi, type ModuleStatus } from '@/api/modules'
|
||||
import { log } from '@/utils/logger'
|
||||
import { parseApiError } from '@/utils/errorParser'
|
||||
|
||||
export const useModuleStore = defineStore('modules', () => {
|
||||
const modules = ref<Record<string, ModuleStatus>>({})
|
||||
@@ -21,9 +22,9 @@ export const useModuleStore = defineStore('modules', () => {
|
||||
try {
|
||||
modules.value = await modulesApi.getAllStatus()
|
||||
loaded.value = true
|
||||
} catch (err: any) {
|
||||
} catch (err: unknown) {
|
||||
log.error('Failed to fetch modules status', err)
|
||||
error.value = err.response?.data?.detail || '获取模块状态失败'
|
||||
error.value = parseApiError(err, '获取模块状态失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -60,9 +61,9 @@ export const useModuleStore = defineStore('modules', () => {
|
||||
// 刷新所有模块状态,确保依赖模块的 active 状态同步更新
|
||||
await fetchModules()
|
||||
return true
|
||||
} catch (err: any) {
|
||||
} catch (err: unknown) {
|
||||
log.error(`Failed to set module ${moduleName} enabled=${enabled}`, err)
|
||||
error.value = err.response?.data?.detail || '设置模块状态失败'
|
||||
error.value = parseApiError(err, '设置模块状态失败')
|
||||
// 重新抛出错误,让调用方可以获取详细错误信息
|
||||
throw err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { proxyNodesApi, type ProxyNode, type ManualProxyNodeCreateRequest } from '@/api/proxy-nodes'
|
||||
import { parseApiError } from '@/utils/errorParser'
|
||||
|
||||
export const useProxyNodesStore = defineStore('proxy-nodes', () => {
|
||||
const nodes = ref<ProxyNode[]>([])
|
||||
@@ -24,8 +25,8 @@ export const useProxyNodesStore = defineStore('proxy-nodes', () => {
|
||||
nodes.value = data.items
|
||||
total.value = data.total
|
||||
fetched.value = true
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '获取代理节点列表失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '获取代理节点列表失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -47,8 +48,8 @@ export const useProxyNodesStore = defineStore('proxy-nodes', () => {
|
||||
// 重新获取列表以保持排序一致
|
||||
await fetchNodes()
|
||||
return result
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '创建手动代理节点失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '创建手动代理节点失败')
|
||||
throw err
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -63,8 +64,8 @@ export const useProxyNodesStore = defineStore('proxy-nodes', () => {
|
||||
await proxyNodesApi.deleteProxyNode(nodeId)
|
||||
nodes.value = nodes.value.filter(n => n.id !== nodeId)
|
||||
total.value = Math.max(0, total.value - 1)
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '删除代理节点失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '删除代理节点失败')
|
||||
throw err
|
||||
} finally {
|
||||
loading.value = false
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { usersApi, type User, type CreateUserRequest, type UpdateUserRequest, type ApiKey } from '@/api/users'
|
||||
import { parseApiError } from '@/utils/errorParser'
|
||||
|
||||
export const useUsersStore = defineStore('users', () => {
|
||||
const users = ref<User[]>([])
|
||||
@@ -13,8 +14,8 @@ export const useUsersStore = defineStore('users', () => {
|
||||
|
||||
try {
|
||||
users.value = await usersApi.getAllUsers()
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '获取用户列表失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '获取用户列表失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -28,8 +29,8 @@ export const useUsersStore = defineStore('users', () => {
|
||||
const newUser = await usersApi.createUser(userData)
|
||||
users.value.push(newUser)
|
||||
return newUser
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '创建用户失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '创建用户失败')
|
||||
throw err
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -51,8 +52,8 @@ export const useUsersStore = defineStore('users', () => {
|
||||
}
|
||||
}
|
||||
return updatedUser
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '更新用户失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '更新用户失败')
|
||||
throw err
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -66,8 +67,8 @@ export const useUsersStore = defineStore('users', () => {
|
||||
try {
|
||||
await usersApi.deleteUser(userId)
|
||||
users.value = users.value.filter(u => u.id !== userId)
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '删除用户失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '删除用户失败')
|
||||
throw err
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -77,8 +78,8 @@ export const useUsersStore = defineStore('users', () => {
|
||||
async function getUserApiKeys(userId: string): Promise<ApiKey[]> {
|
||||
try {
|
||||
return await usersApi.getUserApiKeys(userId)
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '获取 API Keys 失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '获取 API Keys 失败')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@@ -86,8 +87,8 @@ export const useUsersStore = defineStore('users', () => {
|
||||
async function createApiKey(userId: string, name?: string): Promise<ApiKey> {
|
||||
try {
|
||||
return await usersApi.createApiKey(userId, name)
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '创建 API Key 失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '创建 API Key 失败')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@@ -95,8 +96,8 @@ export const useUsersStore = defineStore('users', () => {
|
||||
async function deleteApiKey(userId: string, keyId: string) {
|
||||
try {
|
||||
await usersApi.deleteApiKey(userId, keyId)
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '删除 API Key 失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '删除 API Key 失败')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@@ -109,8 +110,8 @@ export const useUsersStore = defineStore('users', () => {
|
||||
await usersApi.resetUserQuota(userId)
|
||||
// 刷新用户列表以获取最新数据
|
||||
await fetchUsers()
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '重置配额失败'
|
||||
} catch (err: unknown) {
|
||||
error.value = parseApiError(err, '重置配额失败')
|
||||
throw err
|
||||
} finally {
|
||||
loading.value = false
|
||||
@@ -130,4 +131,4 @@ export const useUsersStore = defineStore('users', () => {
|
||||
deleteApiKey,
|
||||
resetUserQuota
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user