package apierror import ( "fmt" "testing" ) // ============================================================ // classifyConnectionError 测试 // ============================================================ func TestClassifyConnectionError_SSL(t *testing.T) { err := classifyConnectionError(fmt.Errorf("tls: failed to verify certificate: x509: certificate signed by unknown authority")) if err.ErrCategory != ErrSSL { t.Errorf("Category = %v, want ErrSSL", err.ErrCategory) } if !err.IsRetryable() { t.Error("SSL errors should be retryable by default (cert might be renewed)") } } func TestClassifyConnectionError_Timeout(t *testing.T) { err := classifyConnectionError(&mockTimeoutError{msg: "dial tcp: i/o timeout"}) if err.ErrCategory != ErrTimeout { t.Errorf("Category = %v, want ErrTimeout", err.ErrCategory) } } func TestClassifyConnectionError_Generic(t *testing.T) { err := classifyConnectionError(fmt.Errorf("dial tcp: connection refused")) if err.ErrCategory != ErrConnection { t.Errorf("Category = %v, want ErrConnection", err.ErrCategory) } } // ============================================================ // isSSLError 测试 // ============================================================ func TestIsSSLError(t *testing.T) { tests := []struct { msg string want bool }{ {"tls: handshake failure", true}, {"x509: certificate signed by unknown authority", true}, {"UNABLE_TO_VERIFY_LEAF_SIGNATURE", true}, {"dial tcp: connection refused", false}, {"some random error", false}, } for _, tt := range tests { if got := isSSLError(fmt.Errorf("%s", tt.msg)); got != tt.want { t.Errorf("isSSLError(%q) = %v, want %v", tt.msg, got, tt.want) } } } // ============================================================ // isTimeoutError 测试 // ============================================================ func TestIsTimeoutError(t *testing.T) { // net.Error 接口 if !isTimeoutError(&mockTimeoutError{msg: "timeout"}) { t.Error("mockTimeoutError should be detected as timeout") } // 字符串回退 if !isTimeoutError(fmt.Errorf("context deadline exceeded")) { t.Error("deadline exceeded should be detected as timeout") } // 非超时 if isTimeoutError(fmt.Errorf("connection refused")) { t.Error("connection refused should NOT be timeout") } } // ============================================================ // 测试辅助 // ============================================================ // mockTimeoutError 实现 net.Error 接口,Timeout() 恒为 true,用于测试超时分类. // (transport 包的 classifier_test.go 保留同名类型供其本地测试使用.) type mockTimeoutError struct { msg string } func (e *mockTimeoutError) Error() string { return e.msg } func (e *mockTimeoutError) Timeout() bool { return true } func (e *mockTimeoutError) Temporary() bool { return true }