diff --git a/.gitignore b/.gitignore index 0e1b095..0eaaead 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ dist # core 后端环境变量需要进 CI 构建,放行它(其余 .env 仍忽略) !core/backend/.env .venv +.idea/ __pycache__/ *.pyc db.sqlite3 @@ -33,3 +34,4 @@ docs/bug_todo/ # pnpm 本地内容寻址存储 .pnpm-store/ + diff --git a/core/backend/apps/ai/generation_errors.py b/core/backend/apps/ai/generation_errors.py index 3e6738a..b5db56a 100644 --- a/core/backend/apps/ai/generation_errors.py +++ b/core/backend/apps/ai/generation_errors.py @@ -369,6 +369,8 @@ def classify_generation_error( compact_code = re.sub(r"[^a-z0-9]", "", provider_code.lower()) # 内容审核必须先于 HTTP 403 判断:部分供应商会以 403 返回 policy violation。 + if _contains(signal, "insufficient credit", "余额不足", "额度不足", "credit limit exceeded"): + return _build_error("user_credit_insufficient", operation, reference_id=reference_id) if _contains(signal, "moderation_blocked", "safety_violation", "safety system", "content_policy", "policyviolation", "sensitivecontentdetected"): return _build_error("content_rejected", operation, reference_id=reference_id) if ( diff --git a/core/backend/apps/ai/test_generation_errors.py b/core/backend/apps/ai/test_generation_errors.py index f270fff..b7049d3 100644 --- a/core/backend/apps/ai/test_generation_errors.py +++ b/core/backend/apps/ai/test_generation_errors.py @@ -78,6 +78,15 @@ class GenerationErrorClassifierTests(SimpleTestCase): self.assertEqual(error.code, "user_credit_insufficient") self.assertEqual(error.action, "recharge") + def test_insufficient_credit_is_detected_without_manual_internal_kind(self): + error = classify_generation_error( + ValueError("insufficient credit"), + operation="video_generate", + ) + self.assertEqual(error.code, "user_credit_insufficient") + self.assertEqual(error.action, "recharge") + self.assertIn("积分不足", error.fallback_message) + def test_moderation_takes_precedence_over_403(self): error = classify_generation_error( _http_error(403, "PolicyViolation", "safety_violation"),