Files
NianAIGC/backend/internal/providers/failure_messages_test.go
T
2026-10-02 19:56:32 +08:00

81 lines
6.9 KiB
Go

package providers
import (
"strings"
"testing"
)
func TestFailureMessageUsesProviderSpecificCodes(t *testing.T) {
cases := []struct {
name, provider, code, want string
status int
}{
{"seedance real-person image", "seedance", "InputImageSensitiveContentDetected.PrivacyInformation", "参考图片可能包含真人,未通过服务商审核;请更换符合要求的图片后重试。", 400},
{"seedream real-person image", "seedream", "InputImageSensitiveContentDetected.PrivacyInformation", "参考图片可能包含真人,未通过服务商审核;请更换符合要求的图片后重试。", 400},
{"seedance real-person video", "seedance", "InputVideoSensitiveContentDetected.PrivacyInformation", "参考视频可能包含真人,未通过服务商审核;请更换符合要求的视频后重试。", 400},
{"seedance image copyright", "seedance", "InputImageSensitiveContentDetected.PolicyViolation", "参考图片可能涉及版权限制,请调整内容后重试。", 400},
{"seedance image subcode", "seedance", "InputImageSensitiveContentDetected.OtherRestriction", "参考图片未通过服务商内容审核,请调整内容后重试。", 400},
{"seedance parameter subcode", "seedance", "InvalidParameter.NewConstraint", "当前生成参数不符合模型要求,请调整设置或切换模型后重试。", 400},
{"seedance missing parameter subcode", "seedance", "MissingParameter.ImageURL", "当前生成参数不符合模型要求,请调整设置或切换模型后重试。", 400},
{"seedance audio moderation", "seedance", "InputAudioSensitiveContentDetected", "参考音频未通过服务商内容审核,请调整内容后重试。", 400},
{"seedance output video moderation", "seedance", "OutputVideoSensitiveContentDetected", "生成的视频未通过服务商内容审核,请调整内容后重试。", 400},
{"seedream old output image moderation", "seedream", "OutputImageSensitiveContentDetected", "生成的图片未通过服务商内容审核,请调整内容后重试。", 400},
{"seedance account overdue", "seedance", "OperationDenied.ServiceOverdue", "生成服务账户已逾期,请联系管理员处理。", 403},
{"seedance service unopened", "seedance", "OperationDenied.ServiceNotOpen", "当前模型服务尚未开通或无权使用,请联系管理员处理。", 403},
{"minimax balance", "minimax", "1008", "MiniMax 生成服务账户余额不足,请联系管理员处理。", 400},
{"minimax moderation", "minimax", "1026", "视频描述或参考素材未通过 MiniMax 内容审核,请调整后重试。", 400},
{"minimax rate limit", "minimax", "1002", "MiniMax 请求过于频繁,请稍后重试。", 400},
{"minimax invalid parameters", "minimax", "2013", "当前生成参数不符合 MiniMax 模型要求,请调整设置后重试。", 400},
{"bailian arrearage", "bailian", "Arrearage", "百炼生成服务账户余额不足或逾期,请联系管理员处理。", 400},
{"bailian copyright", "bailian", "IPInfringementSuspect", "输入内容可能涉及知识产权限制,请调整提示词或素材后重试。", 400},
{"bailian inspection", "bailian", "DataInspectionFailed", "输入或生成内容未通过百炼审核,请调整提示词或素材后重试。", 400},
{"bailian reference download", "bailian", "InvalidFile.DownloadFailed", "参考素材无法下载,请重新上传可访问的素材后重试。", 400},
{"bailian inspection access", "bailian", "InvalidParameter.DataInspection", "参考素材在安全审核时无法访问,请重新上传素材;若仍失败请联系管理员。", 400},
{"evolink balance by status", "evolink", "unrecognized", "生成服务账户额度不足,请联系管理员处理。", 402},
{"evolink invalid request by code", "evolink", "invalid_request", "当前生成参数不符合模型要求,请检查提示词、素材和设置后重试。", 400},
{"evolink quota by code", "evolink", "insufficient_quota", "EvoLink 生成服务账户额度不足,请联系管理员处理。", 400},
{"evolink model access by code", "evolink", "model_access_denied", "当前 EvoLink 模型无调用权限,请联系管理员处理。", 400},
{"jimeng text audit by business code", "volcengine-visual", "50413", "提示词未通过即梦内容审核,请调整内容后重试。", 200},
{"jimeng image audit by business code", "volcengine-visual", "50411", "参考图片未通过即梦内容审核,请更换图片后重试。", 200},
{"jimeng image too large by business code", "volcengine-visual", "50205", "参考图片过大、为空或无法读取,请更换图片后重试。", 200},
{"jimeng concurrency by business code", "volcengine-visual", "50430", "即梦请求频率或并发达到上限,请稍后重试。", 200},
{"jimeng forbidden by status", "volcengine-visual", "unrecognized", "当前生成服务无权使用,请联系管理员处理。", 403},
{"unknown authorization", "evolink", "unrecognized", "生成服务鉴权失败,请联系管理员处理。", 401},
{"unknown model", "evolink", "unrecognized", "模型或生成任务不存在,请联系管理员检查配置。", 404},
{"unknown validation", "evolink", "unrecognized", "服务商拒绝了本次请求,请联系管理员查看错误详情。", 422},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if got := FailureMessage(tc.provider, tc.status, tc.code); got != tc.want {
t.Errorf("FailureMessage(%q, %d, %q) = %q; want %q", tc.provider, tc.status, tc.code, got, tc.want)
}
})
}
}
func TestFailureMessageUnknownCodesStayGenericAndDoNotCrossProvider(t *testing.T) {
cases := []struct {
provider, code string
status int
want string
}{
{"seedance", "InputImageSensitiveContentDetectedEvil.PrivacyInformation", 400, "服务商拒绝了本次请求,请联系管理员查看错误详情。"},
{"evolink", "InputImageSensitiveContentDetected.PrivacyInformation", 400, "服务商拒绝了本次请求,请联系管理员查看错误详情。"},
{"minimax", "OperationDenied.ServiceOverdue", 400, "服务商拒绝了本次请求,请联系管理员查看错误详情。"},
{"unknown", "1008", 400, "服务商拒绝了本次请求,请联系管理员查看错误详情。"},
{"bailian", "unknown", 0, "服务商未能完成生成,请联系管理员查看错误详情。"},
{"seedream", "unknown", 429, "生成服务请求频率过高,请稍后重试。"},
{"seedream", "unknown", 504, "服务商请求超时,无法确认是否已接收,请联系管理员核查任务状态。"},
{"seedream", "unknown", 500, "生成服务暂时异常,请稍后重试。"},
}
for _, tc := range cases {
got := FailureMessage(tc.provider, tc.status, tc.code)
if got != tc.want {
t.Errorf("FailureMessage(%q, %d, %q) = %q; want %q", tc.provider, tc.status, tc.code, got, tc.want)
}
if strings.Contains(got, tc.code) && tc.code != "unknown" {
t.Errorf("user message leaked provider code %q: %q", tc.code, got)
}
}
}