From f5b7e829e280ca48653dba0c11a2f92353e16392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=96=87=E9=94=8B0668000834?= Date: Fri, 13 Mar 2026 09:44:13 +0800 Subject: [PATCH] test(providers): add tests for transport error classification Add comprehensive tests for transport-level connection errors: - connection reset by peer - connection refused - no route to host - unexpected eof - broken pipe - network is unreachable - connection closed - tls handshake error - read/write tcp errors These tests verify that transport errors are correctly classified as FailoverTimeout and are retriable, allowing the fallback chain to continue. Related to #1419 --- pkg/providers/error_classifier_test.go | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/pkg/providers/error_classifier_test.go b/pkg/providers/error_classifier_test.go index 67d9af62b..f32755d2f 100644 --- a/pkg/providers/error_classifier_test.go +++ b/pkg/providers/error_classifier_test.go @@ -154,6 +154,37 @@ func TestClassifyError_TimeoutPatterns(t *testing.T) { } } +func TestClassifyError_TransportErrorPatterns(t *testing.T) { + patterns := []string{ + "connection reset by peer", + "connection refused", + "no route to host", + "unexpected eof", + "broken pipe", + "network is unreachable", + "connection closed", + "tls handshake error", + "read tcp 192.168.1.1:12345: connection reset by peer", + "write tcp connection refused", + } + + for _, msg := range patterns { + err := errors.New(msg) + result := ClassifyError(err, "openrouter", "stepfun/step-3.5-flash") + if result == nil { + t.Errorf("pattern %q: expected non-nil", msg) + continue + } + // Transport errors are treated as timeout (retriable) + if result.Reason != FailoverTimeout { + t.Errorf("pattern %q: reason = %q, want timeout", msg, result.Reason) + } + if !result.IsRetriable() { + t.Errorf("pattern %q: should be retriable", msg) + } + } +} + func TestClassifyError_AuthPatterns(t *testing.T) { patterns := []string{ "invalid api key",