Files
art-design/src/utils/http/error.ts
T

141 lines
3.6 KiB
TypeScript
Raw Normal View History

2025-07-04 17:16:38 +08:00
import { AxiosError } from 'axios'
import { ElMessage } from 'element-plus'
import { ApiStatus } from './status'
import { $t } from '@/locales'
// 错误响应接口
export interface ErrorResponse {
code: number
2025-07-11 18:37:16 +08:00
message: string
2025-07-04 17:16:38 +08:00
data?: unknown
}
// 错误日志数据接口
export interface ErrorLogData {
code: number
message: string
data?: unknown
timestamp: string
url?: string
method?: string
stack?: string
}
// 自定义 HttpError 类
export class HttpError extends Error {
public readonly code: number
public readonly data?: unknown
public readonly timestamp: string
public readonly url?: string
public readonly method?: string
constructor(
message: string,
code: number,
options?: {
data?: unknown
url?: string
method?: string
}
) {
super(message)
this.name = 'HttpError'
this.code = code
this.data = options?.data
this.timestamp = new Date().toISOString()
this.url = options?.url
this.method = options?.method
}
public toLogData(): ErrorLogData {
return {
code: this.code,
message: this.message,
data: this.data,
timestamp: this.timestamp,
url: this.url,
method: this.method,
stack: this.stack
}
}
}
/**
* 获取错误消息
* @param status 错误状态码
* @returns 错误消息
*/
const getErrorMessage = (status: number): string => {
const errorMap: Record<number, string> = {
[ApiStatus.unauthorized]: 'httpMsg.unauthorized',
[ApiStatus.forbidden]: 'httpMsg.forbidden',
[ApiStatus.notFound]: 'httpMsg.notFound',
[ApiStatus.methodNotAllowed]: 'httpMsg.methodNotAllowed',
[ApiStatus.requestTimeout]: 'httpMsg.requestTimeout',
[ApiStatus.internalServerError]: 'httpMsg.internalServerError',
[ApiStatus.badGateway]: 'httpMsg.badGateway',
[ApiStatus.serviceUnavailable]: 'httpMsg.serviceUnavailable',
[ApiStatus.gatewayTimeout]: 'httpMsg.gatewayTimeout'
}
return $t(errorMap[status] || 'httpMsg.internalServerError')
}
/**
* 处理错误
* @param error 错误对象
* @returns 错误对象
*/
export function handleError(error: AxiosError<ErrorResponse>): never {
// 处理取消的请求
if (error.code === 'ERR_CANCELED') {
console.warn('Request cancelled:', error.message)
throw new HttpError($t('httpMsg.requestCancelled'), ApiStatus.error)
}
const statusCode = error.response?.status
2025-07-11 18:37:16 +08:00
const errorMessage = error.response?.data?.message || error.message
2025-07-04 17:16:38 +08:00
const requestConfig = error.config
// 处理网络错误
if (!error.response) {
throw new HttpError($t('httpMsg.networkError'), ApiStatus.error, {
url: requestConfig?.url,
method: requestConfig?.method?.toUpperCase()
})
}
// 处理 HTTP 状态码错误
2025-07-11 18:37:16 +08:00
// const message = statusCode
// ? getErrorMessage(statusCode)
// : errorMessage || $t('httpMsg.requestFailed')
const message = errorMessage
2025-07-04 17:16:38 +08:00
throw new HttpError(message, statusCode || ApiStatus.error, {
data: error.response.data,
url: requestConfig?.url,
method: requestConfig?.method?.toUpperCase()
})
}
/**
* 显示错误消息
* @param error 错误对象
* @param showMessage 是否显示错误消息
*/
export function showError(error: HttpError, showMessage: boolean = true): void {
if (showMessage) {
ElMessage.error(error.message)
}
// 记录错误日志
2025-07-11 18:37:16 +08:00
// console.error('[HTTP Error]', error.toLogData())
2025-07-04 17:16:38 +08:00
}
/**
* 判断是否为 HttpError 类型
* @param error 错误对象
* @returns 是否为 HttpError 类型
*/
export const isHttpError = (error: unknown): error is HttpError => {
return error instanceof HttpError
}