feat: add unified API error handler with user-friendly messages
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export interface ApiError {
|
||||
code: string
|
||||
message: string
|
||||
details?: Record<string, any>
|
||||
timestamp: string
|
||||
path: string
|
||||
}
|
||||
|
||||
export class ApiErrorHandler {
|
||||
static handle(error: any): void {
|
||||
if (!error.response) {
|
||||
this.handleNetworkError(error)
|
||||
return
|
||||
}
|
||||
|
||||
const { status, data } = error.response
|
||||
const apiError = data as ApiError
|
||||
|
||||
switch (status) {
|
||||
case 400:
|
||||
this.handleBadRequest(apiError)
|
||||
break
|
||||
case 401:
|
||||
this.handleUnauthorized(apiError)
|
||||
break
|
||||
case 403:
|
||||
this.handleForbidden(apiError)
|
||||
break
|
||||
case 404:
|
||||
this.handleNotFound(apiError)
|
||||
break
|
||||
case 409:
|
||||
this.handleConflict(apiError)
|
||||
break
|
||||
case 422:
|
||||
this.handleValidationError(apiError)
|
||||
break
|
||||
case 500:
|
||||
this.handleInternalServerError(apiError)
|
||||
break
|
||||
case 502:
|
||||
case 503:
|
||||
case 504:
|
||||
this.handleServiceUnavailable(apiError)
|
||||
break
|
||||
default:
|
||||
this.handleUnknownError(apiError)
|
||||
}
|
||||
}
|
||||
|
||||
private static handleNetworkError(error: any): void {
|
||||
ElMessage.error('网络连接失败,请检查网络设置')
|
||||
console.error('Network Error:', error)
|
||||
}
|
||||
|
||||
private static handleBadRequest(error: ApiError): void {
|
||||
ElMessage.error(error.message || '请求参数错误')
|
||||
console.error('Bad Request:', error)
|
||||
}
|
||||
|
||||
private static handleUnauthorized(error: ApiError): void {
|
||||
ElMessage.error('登录已过期,请重新登录')
|
||||
localStorage.removeItem('token')
|
||||
window.location.href = '/login'
|
||||
console.error('Unauthorized:', error)
|
||||
}
|
||||
|
||||
private static handleForbidden(error: ApiError): void {
|
||||
ElMessage.error('没有权限访问该资源')
|
||||
console.error('Forbidden:', error)
|
||||
}
|
||||
|
||||
private static handleNotFound(error: ApiError): void {
|
||||
ElMessage.error(error.message || '请求的资源不存在')
|
||||
console.error('Not Found:', error)
|
||||
}
|
||||
|
||||
private static handleConflict(error: ApiError): void {
|
||||
ElMessage.error(error.message || '资源冲突,请刷新后重试')
|
||||
console.error('Conflict:', error)
|
||||
}
|
||||
|
||||
private static handleValidationError(error: ApiError): void {
|
||||
if (error.details) {
|
||||
const messages = Object.values(error.details).join('、')
|
||||
ElMessage.error(messages)
|
||||
} else {
|
||||
ElMessage.error(error.message || '数据验证失败')
|
||||
}
|
||||
console.error('Validation Error:', error)
|
||||
}
|
||||
|
||||
private static handleInternalServerError(error: ApiError): void {
|
||||
ElMessage.error('服务器内部错误,请稍后重试')
|
||||
console.error('Internal Server Error:', error)
|
||||
}
|
||||
|
||||
private static handleServiceUnavailable(error: ApiError): void {
|
||||
ElMessage.error('服务暂时不可用,请稍后重试')
|
||||
console.error('Service Unavailable:', error)
|
||||
}
|
||||
|
||||
private static handleUnknownError(error: ApiError): void {
|
||||
ElMessage.error(error.message || '未知错误')
|
||||
console.error('Unknown Error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
export const handleApiError = (error: any): void => {
|
||||
ApiErrorHandler.handle(error)
|
||||
}
|
||||
Reference in New Issue
Block a user