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