Files
omniai-ds-code-package/src/utils/translateTaskError.ts
T

176 lines
5.4 KiB
TypeScript

/**
* Translate API error messages to user-friendly Chinese.
*
* Classifies errors into categories and provides user-friendly messages
* with suggested recovery actions.
*/
export type TaskErrorCategory =
| "content_policy"
| "auth_failure"
| "insufficient_balance"
| "unsupported_model"
| "concurrency_busy"
| "invalid_asset"
| "network_failure"
| "timeout"
| "cancelled"
| "unknown";
export interface TaskErrorInfo {
category: TaskErrorCategory;
message: string;
action: string;
}
const ERROR_RULES: Array<{
pattern: RegExp;
category: TaskErrorCategory;
message: string;
action: string;
}> = [
// Content policy
{
pattern: /violated? our (?:relevant )?policies|content policies|violated? content policy|content.*filter|safety.*filter|moderation|blocked by.*filter|nsfw|inappropriate|explicit.*content|adult.*content/i,
category: "content_policy",
message: "输入词汇包含违规信息,已停止生成",
action: "修改提示词后重试",
},
// Auth failure
{
pattern: /unauthorized|authentication.*fail|invalid.*token|token.*expired|session.*expired|401|login.*required/i,
category: "auth_failure",
message: "登录已过期,请重新登录",
action: "重新登录",
},
// Insufficient balance
{
pattern: /insufficient.*balance|余额不足|积分不足|INSUFFICIENT_BALANCE|balance.*not.*enough|402/i,
category: "insufficient_balance",
message: "余额不足,请充值后重试",
action: "去充值",
},
// Concurrency busy
{
pattern: /concurrency pool.*full|pool is full|concurrency.*limit|too many.*concurrent|排队繁忙/i,
category: "concurrency_busy",
message: "当前模型排队繁忙,请稍后重试或切换其他模型",
action: "稍后重试或切换模型",
},
// Rate limit
{
pattern: /rate limit|too many requests|429/i,
category: "concurrency_busy",
message: "请求过于频繁,请稍后再试",
action: "稍后重试",
},
// Unsupported model
{
pattern: /unsupported.*model|model.*not.*support|model.*not.*found|ENTERPRISE_VIDEO_MODEL_NOT_ALLOWED|not.*available/i,
category: "unsupported_model",
message: "当前模型暂不可用,请切换其他模型重试",
action: "切换模型",
},
// Invalid asset / upload
{
pattern: /upload.*fail|asset.*fail|素材|invalid.*image|invalid.*video|file.*too.*large/i,
category: "invalid_asset",
message: "素材上传失败,请重新上传后重试",
action: "重新上传素材",
},
// Network failure
{
pattern: /network|connection|fetch failed|ECONNREFUSED|ENOTFOUND|socket.*hang/i,
category: "network_failure",
message: "网络错误,请检查网络后重试",
action: "检查网络后重试",
},
// Timeout
{
pattern: /timeout|timed? out|ETIMEDOUT/i,
category: "timeout",
message: "任务超时,请稍后在任务历史中查看结果",
action: "稍后重试",
},
// Quota exceeded
{
pattern: /quota exceeded|quota.*limit/i,
category: "insufficient_balance",
message: "配额已用完,请联系管理员",
action: "联系管理员",
},
// Cancelled
{
pattern: /cancelled|已取消/i,
category: "cancelled",
message: "已取消",
action: "重新开始",
},
// All providers failed
{
pattern: /all.*providers.*failed|provider.*fail/i,
category: "concurrency_busy",
message: "所有可用模型均暂时不可用,请稍后重试",
action: "稍后重试",
},
// Upstream / service error
{
pattern: /upstream.*error|文本服务返回|服务返回.*HTTP|openai_error|internal.*server.*error|500|502|503/i,
category: "network_failure",
message: "AI 服务暂时不可用,请稍后重试",
action: "稍后重试",
},
// Access denied / forbidden
{
pattern: /access.*denied|forbidden|403|permission.*denied|权限/i,
category: "auth_failure",
message: "模型权限未开通,请联系管理员",
action: "联系管理员",
},
// Image format / size issues
{
pattern: /image.*too.*large|image.*format|图片.*大小|图片.*格式|invalid.*file.*type/i,
category: "invalid_asset",
message: "图片格式或大小不符合要求,请调整后重试",
action: "调整图片后重试",
},
// Aborted (user or timeout abort)
{
pattern: /aborted|abort/i,
category: "timeout",
message: "请求已中断,请重试",
action: "重试",
},
];
/**
* Classify an API error into a structured result with category, message, and action.
*/
export function classifyTaskError(error: string | undefined | null): TaskErrorInfo {
if (!error) {
return { category: "unknown", message: "任务失败,请重试", action: "重试" };
}
for (const rule of ERROR_RULES) {
if (rule.pattern.test(error)) {
return { category: rule.category, message: rule.message, action: rule.action };
}
}
const hasChinese = /[一-鿿]/.test(error);
if (hasChinese) {
const truncated = error.length > 80 ? `${error.slice(0, 80)}...` : error;
return { category: "unknown", message: truncated, action: "重试" };
}
return { category: "unknown", message: "服务异常,请稍后重试", action: "重试" };
}
/**
* Translate an API error message to a user-friendly Chinese message.
* Convenience wrapper around classifyTaskError.
*/
export function translateTaskError(error: string | undefined | null): string {
return classifyTaskError(error).message;
}