From ffbe69c2d97b6816bd3d8d60b104750690953e57 Mon Sep 17 00:00:00 2001 From: muava12 Date: Wed, 25 Feb 2026 00:16:57 +0800 Subject: [PATCH] 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. --- pkg/providers/error_classifier.go | 8 +++++--- pkg/providers/error_classifier_test.go | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/providers/error_classifier.go b/pkg/providers/error_classifier.go index 33478f086..5563e669e 100644 --- a/pkg/providers/error_classifier.go +++ b/pkg/providers/error_classifier.go @@ -182,11 +182,13 @@ func ClassifyError(err error, provider, model string) *FailoverError { } // classifyByStatus maps HTTP status codes to FailoverReason. -// NOTE: 400 is intentionally NOT mapped here. Status 400 is too broad -// (model-invalid, format errors, unknown API errors all return 400). -// Instead, 400 errors are classified by message patterns in classifyByMessage. +// NOTE: 400 maps to FailoverModelInvalid (retriable) — not FailoverFormat. +// This ensures all 400 errors show a warning and fallback to the next model. +// Specific 400 patterns (like model-invalid) are caught earlier by message matching. func classifyByStatus(status int) FailoverReason { switch { + case status == 400: + return FailoverModelInvalid case status == 401 || status == 403: return FailoverAuth case status == 402: diff --git a/pkg/providers/error_classifier_test.go b/pkg/providers/error_classifier_test.go index 8637cf865..b9a6b035a 100644 --- a/pkg/providers/error_classifier_test.go +++ b/pkg/providers/error_classifier_test.go @@ -41,7 +41,7 @@ func TestClassifyError_StatusCodes(t *testing.T) { {402, FailoverBilling}, {408, FailoverTimeout}, {429, FailoverRateLimit}, - // 400 is intentionally NOT here - classified by message patterns, not status code + {400, FailoverModelInvalid}, {500, FailoverTimeout}, {502, FailoverTimeout}, {503, FailoverTimeout},