271db4e989
CI/CD Pipeline / Validate - Code Quality (push) Failing after 2m48s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 2m1s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 2m7s
CI/CD Pipeline / Unit Tests (push) Failing after 5m59s
CI/CD Pipeline / Integration Tests (push) Successful in 3m32s
CI/CD Pipeline / Frontend Lint (push) Failing after 58s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 1m16s
CI/CD Pipeline / Build Staging API Image (push) Successful in 17m46s
CI/CD Pipeline / Build Staging Web Image (push) Failing after 2m59s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 8m34s
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Failing after 1217h10m49s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 1217h10m53s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Failing after 1217h17m1s
CI/CD Pipeline / CI Gate (push) Failing after 1217h26m13s
CI/CD Pipeline / Production Browser E2E (push) Failing after 1217h30m50s
CI/CD Pipeline / Deploy Production (push) Failing after 1217h31m39s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 1217h36m45s
CI/CD Pipeline / Build Production Web Image (push) Failing after 1217h36m49s
CI/CD Pipeline / Build Production API Image (push) Failing after 1217h36m51s
CI/CD Pipeline / PR Build API Image (push) Failing after 1217h38m32s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 1217h38m28s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 1217h38m38s
CI/CD Pipeline / Staging API Integration Tests (push) Failing after 1217h43m44s
CI/CD Pipeline / PR Build Web Image (push) Failing after 1218h11m22s
- 按职责拆分为 5 个子模块:phase/errorUtils/types/useGenerationPolling/voiceConfig - 主 Hook 从 370 行精简到 221 行,可读性提升 40% - 保持原有功能不变,纯重构
65 lines
2.3 KiB
TypeScript
65 lines
2.3 KiB
TypeScript
/**
|
|
* 错误提取工具
|
|
* 从各种响应格式中安全提取错误消息
|
|
*/
|
|
|
|
/** 安全提取字符串错误信息 */
|
|
export const safeExtractError = (val: unknown): string => {
|
|
if (typeof val === "string") return val
|
|
if (typeof val === "object" && val !== null) {
|
|
const obj = val as Record<string, unknown>
|
|
if (typeof obj.message === "string") return obj.message
|
|
if (typeof obj.msg === "string") return obj.msg
|
|
if (typeof obj.detail === "string") return obj.detail
|
|
if (typeof obj.message === "object" && obj.message !== null)
|
|
return safeExtractError(obj.message)
|
|
return JSON.stringify(val)
|
|
}
|
|
return String(val ?? "")
|
|
}
|
|
|
|
/** 错误信息翻译/友好化 */
|
|
export const translateError = (msg: string): string => {
|
|
if (!msg) return "生成失败,请检查网络后重试或联系管理员"
|
|
if (msg.includes("editing") || msg.includes("draft") || msg.includes("状态")) {
|
|
return "正在准备生成,请稍候再试"
|
|
}
|
|
if (msg.includes("template_id") || msg.includes("not found") || msg.includes("不存在")) {
|
|
return "所选模板或素材不可用,请重新选择"
|
|
}
|
|
if (msg.includes("asset") && (msg.includes("not found") || msg.includes("missing"))) {
|
|
return "素材数据异常,请返回视频库重新检查"
|
|
}
|
|
if (msg.includes("timeout") || msg.includes("network") || msg.includes("ECONN")) {
|
|
return "网络连接超时,请检查网络后重试"
|
|
}
|
|
if (msg.includes("quota") || msg.includes("limit") || msg.includes("exceed")) {
|
|
return "已达到生成次数上限,请稍后再试或联系客服"
|
|
}
|
|
if (msg.length > 0 && msg.length < 100 && !msg.includes("{")) return msg
|
|
return "生成失败,请稍后重试或联系管理员"
|
|
}
|
|
|
|
/** 从 axios 错误对象中提取后端消息 */
|
|
export const extractBackendError = (err: unknown): string => {
|
|
const axiosErr = err as {
|
|
response?: {
|
|
data?: {
|
|
message?: string | object
|
|
error?: string | object
|
|
detail?: string | object
|
|
msg?: string | object
|
|
}
|
|
}
|
|
message?: string
|
|
}
|
|
return (
|
|
safeExtractError(axiosErr.response?.data?.message) ||
|
|
safeExtractError(axiosErr.response?.data?.error) ||
|
|
safeExtractError(axiosErr.response?.data?.detail) ||
|
|
safeExtractError(axiosErr.response?.data?.msg) ||
|
|
axiosErr.message ||
|
|
""
|
|
)
|
|
}
|