fix(providers): show warning for all 400 errors before fallback

Map HTTP 400 to FailoverModelInvalid in classifyByStatus so ALL 400
errors trigger a warning message to the user and then fallback to the
next model. This prevents 400 errors with unrecognized messages from
being silently swallowed during fallback.
This commit is contained in:
muava12 2026-02-25 00:16:57 +08:00
parent c16711ee7e
commit ffbe69c2d9
2 changed files with 6 additions and 4 deletions

View file

@ -182,11 +182,13 @@ func ClassifyError(err error, provider, model string) *FailoverError {
} }
// classifyByStatus maps HTTP status codes to FailoverReason. // classifyByStatus maps HTTP status codes to FailoverReason.
// NOTE: 400 is intentionally NOT mapped here. Status 400 is too broad // NOTE: 400 maps to FailoverModelInvalid (retriable) — not FailoverFormat.
// (model-invalid, format errors, unknown API errors all return 400). // This ensures all 400 errors show a warning and fallback to the next model.
// Instead, 400 errors are classified by message patterns in classifyByMessage. // Specific 400 patterns (like model-invalid) are caught earlier by message matching.
func classifyByStatus(status int) FailoverReason { func classifyByStatus(status int) FailoverReason {
switch { switch {
case status == 400:
return FailoverModelInvalid
case status == 401 || status == 403: case status == 401 || status == 403:
return FailoverAuth return FailoverAuth
case status == 402: case status == 402:

View file

@ -41,7 +41,7 @@ func TestClassifyError_StatusCodes(t *testing.T) {
{402, FailoverBilling}, {402, FailoverBilling},
{408, FailoverTimeout}, {408, FailoverTimeout},
{429, FailoverRateLimit}, {429, FailoverRateLimit},
// 400 is intentionally NOT here - classified by message patterns, not status code {400, FailoverModelInvalid},
{500, FailoverTimeout}, {500, FailoverTimeout},
{502, FailoverTimeout}, {502, FailoverTimeout},
{503, FailoverTimeout}, {503, FailoverTimeout},