This commit is contained in:
2026-08-12 14:08:33 +08:00
parent 4fb8b85c13
commit 975e0057e3
20 changed files with 378 additions and 29 deletions
+19 -2
View File
@@ -38,7 +38,7 @@ describe('API error diagnostics', () => {
unwrapApiResponse({ code: 'A0403', message: '无权限', data: null, requestId: 'request-1', traceId: 'trace-1' })
} catch (error) {
expect(getApiErrorDetails(error)).toEqual({
message: '无权限',
message: '当前账号无权访问该数据,请联系管理员确认权限',
code: 'A0403',
requestId: 'request-1',
traceId: 'trace-1',
@@ -56,13 +56,30 @@ describe('API error diagnostics', () => {
})
expect(getApiErrorDetails(error)).toEqual({
message: '服务不可用',
message: '服务暂时不可用,请稍后重试',
code: 'S0503',
requestId: 'request-2',
traceId: 'trace-2',
})
})
it('uses safe actionable messages for HTTP authentication and permission failures', () => {
const createError = (status: number, data: unknown) => new axios.AxiosError('Request failed', 'ERR_BAD_RESPONSE', undefined, undefined, {
status,
statusText: 'Request failed',
headers: {},
config: { headers: new AxiosHeaders() },
data,
})
expect(getApiErrorDetails(createError(401, { message: 'token parse stack' })).message)
.toBe('登录状态已失效,请重新登录')
expect(getApiErrorDetails(createError(403, { message: 'policy engine details' })).message)
.toBe('当前账号无权访问该数据,请联系管理员确认权限')
expect(getApiErrorDetails(createError(502, '<html>upstream failed</html>')).message)
.toBe('服务暂时不可用,请稍后重试')
})
it('explains a proxy 413 response without a JSON error envelope', () => {
const error = new axios.AxiosError('Request failed', 'ERR_BAD_REQUEST', undefined, undefined, {
status: 413,
+18 -5
View File
@@ -113,7 +113,14 @@ export function unwrapApiResponse<T>(response: ApiEnvelope<T>): T {
export function getApiErrorDetails(error: unknown, fallback = '接口请求失败'): ApiErrorDetails {
if (error instanceof ApiResponseError) {
return { message: error.message, code: error.code, requestId: error.requestId, traceId: error.traceId }
const message = error.code === 'A0401'
? '登录状态已失效,请重新登录'
: error.code === 'A0403'
? '当前账号无权访问该数据,请联系管理员确认权限'
: error.code.startsWith('S05')
? '服务暂时不可用,请稍后重试'
: error.message
return { message, code: error.code, requestId: error.requestId, traceId: error.traceId }
}
if (axios.isAxiosError(error)) {
const response = error.response?.data as {
@@ -124,11 +131,17 @@ export function getApiErrorDetails(error: unknown, fallback = '接口请求失
traceId?: string | null
} | undefined
const status = error.response?.status
const statusMessage = status === 413
? '上传文件的请求体过大,服务器已拒绝;请压缩后重试,如文件未超过 5MB,请联系管理员检查网关上传限制'
: undefined
const statusMessage = status === 401
? '登录状态已失效,请重新登录'
: status === 403
? '当前账号无权访问该数据,请联系管理员确认权限'
: status === 413
? '上传文件的请求体过大,服务器已拒绝;请压缩后重试,如文件未超过 5MB,请联系管理员检查网关上传限制'
: status && status >= 500
? '服务暂时不可用,请稍后重试'
: undefined
return {
message: response?.message || response?.error || statusMessage || fallback,
message: statusMessage || response?.message || response?.error || fallback,
code: response?.code || (error.response?.status ? `HTTP_${error.response.status}` : undefined),
requestId: response?.requestId || undefined,
traceId: response?.traceId || undefined,