Преглед на файлове

fix: 特征对齐 Node 版

hank9999 преди 1 месец
родител
ревизия
ac4823f3be
променени са 3 файла, в които са добавени 36 реда и са изтрити 25 реда
  1. 6 6
      internal/config/loader.go
  2. 1 1
      internal/database/redis.go
  3. 29 18
      internal/pkg/errors/errors.go

+ 6 - 6
internal/config/loader.go

@@ -99,7 +99,7 @@ func setDefaults(v *viper.Viper) {
 	v.SetDefault("redis.read_timeout", 3*time.Second)
 	v.SetDefault("redis.write_timeout", 3*time.Second)
 	v.SetDefault("redis.tls_reject_unauthorized", true) // 与 Node.js 版本一致
-	v.SetDefault("redis.max_retries", 3)
+	v.SetDefault("redis.max_retries", 5)                // 与 Node.js 版本一致:最多重试 5 次
 	v.SetDefault("redis.min_retry_backoff", 200*time.Millisecond)
 	v.SetDefault("redis.max_retry_backoff", 2*time.Second)
 	v.SetDefault("redis.enabled", true)
@@ -112,10 +112,10 @@ func setDefaults(v *viper.Viper) {
 	v.SetDefault("auth.admin_token", "")
 
 	// MessageRequest defaults - 与 Node.js 版本一致
-	v.SetDefault("message_request.write_mode", "async")           // 默认异步写入
-	v.SetDefault("message_request.async_flush_interval_ms", 1000) // 1秒刷新间隔
-	v.SetDefault("message_request.async_batch_size", 100)         // 批量大小
-	v.SetDefault("message_request.async_max_pending", 10000)      // 最大待处理数
+	v.SetDefault("message_request.write_mode", "async")          // 默认异步写入
+	v.SetDefault("message_request.async_flush_interval_ms", 250) // 与 Node.js 版本一致:250ms 刷新间隔
+	v.SetDefault("message_request.async_batch_size", 200)        // 与 Node.js 版本一致:批量大小 200
+	v.SetDefault("message_request.async_max_pending", 10000)     // 最大待处理数
 
 	// Features defaults - 与 Node.js 版本一致
 	v.SetDefault("features.enable_rate_limit", true)
@@ -140,7 +140,7 @@ func setDefaults(v *viper.Viper) {
 	v.SetDefault("smart_probing.timeout_ms", 5000)   // 5秒
 
 	// APITest defaults - 与 Node.js 版本一致
-	v.SetDefault("api_test.timeout_ms", 15000) // 15秒
+	v.SetDefault("api_test.timeout_ms", 15000) // 与 Node.js 版本一致:15秒
 
 	// App defaults
 	v.SetDefault("app.url", "")

+ 1 - 1
internal/database/redis.go

@@ -16,7 +16,7 @@ import (
 
 // 默认配置常量(与 Node.js 版本对齐)
 const (
-	defaultMaxRetries      = 3
+	defaultMaxRetries      = 5 // 与 Node.js 版本一致:最多重试 5 次
 	defaultMinRetryBackoff = 200 * time.Millisecond
 	defaultMaxRetryBackoff = 2 * time.Second
 	defaultPoolSize        = 10

+ 29 - 18
internal/pkg/errors/errors.go

@@ -3,6 +3,7 @@ package errors
 import (
 	"fmt"
 	"net/http"
+	"strings"
 )
 
 // ErrorType 错误类型
@@ -520,23 +521,45 @@ func AsEmptyResponseError(err error) (*EmptyResponseError, bool) {
 // 错误分类函数 - 与 Node.js 版本 categorizeErrorAsync 对齐
 // ============================================================================
 
-// CategorizeError 判断错误类型
+// ErrorRuleChecker 错误规则检测器接口
+// 用于检测错误是否匹配不可重试的客户端输入错误规则
+type ErrorRuleChecker interface {
+	// IsNonRetryableClientError 检查错误是否为不可重试的客户端输入错误
+	// 返回 true 表示该错误匹配了错误规则,应该直接返回给客户端而不重试
+	IsNonRetryableClientError(err error) bool
+}
+
+// CategorizeError 判断错误类型(简化版本,不检测客户端输入错误规则)
+// 分类规则(优先级从高到低):
+// 1. 客户端主动中断 → CategoryClientAbort
+// 2. ProxyError 404 → CategoryResourceNotFound
+// 3. ProxyError 其他 → CategoryProviderError
+// 4. EmptyResponseError → CategoryProviderError
+// 5. 其他 → CategorySystemError
+//
+// 注意:如果需要检测不可重试的客户端输入错误,请使用 CategorizeErrorWithRuleChecker
+func CategorizeError(err error) ErrorCategory {
+	return CategorizeErrorWithRuleChecker(err, nil)
+}
+
+// CategorizeErrorWithRuleChecker 判断错误类型(完整版本,支持错误规则检测)
 // 分类规则(优先级从高到低):
 // 1. 客户端主动中断 → CategoryClientAbort
-// 2. 不可重试的客户端输入错误 → CategoryNonRetryableClientError
+// 2. 不可重试的客户端输入错误(通过 ruleChecker 检测)→ CategoryNonRetryableClientError
 // 3. ProxyError 404 → CategoryResourceNotFound
 // 4. ProxyError 其他 → CategoryProviderError
 // 5. EmptyResponseError → CategoryProviderError
 // 6. 其他 → CategorySystemError
-func CategorizeError(err error) ErrorCategory {
+func CategorizeErrorWithRuleChecker(err error, ruleChecker ErrorRuleChecker) ErrorCategory {
 	// 优先级 1: 客户端中断检测
 	if IsClientAbortError(err) {
 		return CategoryClientAbort
 	}
 
 	// 优先级 2: 不可重试的客户端输入错误(需要配合错误规则检测器)
-	// 注意:这里需要外部调用者提供规则检测结果
-	// Go 版本中可以通过 context 或者单独的检测函数实现
+	if ruleChecker != nil && ruleChecker.IsNonRetryableClientError(err) {
+		return CategoryNonRetryableClientError
+	}
 
 	// 优先级 3: ProxyError
 	if proxyErr, ok := AsProxyError(err); ok {
@@ -589,17 +612,5 @@ func IsClientAbortError(err error) bool {
 
 // contains 检查字符串是否包含子串(不区分大小写)
 func contains(s, substr string) bool {
-	return len(s) >= len(substr) &&
-		(s == substr ||
-			len(s) > len(substr) && findSubstring(s, substr))
-}
-
-// findSubstring 简单的子串查找
-func findSubstring(s, substr string) bool {
-	for i := 0; i <= len(s)-len(substr); i++ {
-		if s[i:i+len(substr)] == substr {
-			return true
-		}
-	}
-	return false
+	return strings.Contains(strings.ToLower(s), strings.ToLower(substr))
 }