优化流式传输&fix bugs
This commit is contained in:
@@ -37,6 +37,7 @@ var (
|
||||
ErrForbidden = &APIError{HTTPStatus: http.StatusForbidden, Code: "FORBIDDEN", Message: "You do not have permission to access this resource"}
|
||||
ErrTaskInProgress = &APIError{HTTPStatus: http.StatusConflict, Code: "TASK_IN_PROGRESS", Message: "A task is already in progress"}
|
||||
ErrBadGateway = &APIError{HTTPStatus: http.StatusBadGateway, Code: "BAD_GATEWAY", Message: "Upstream service error"}
|
||||
ErrGatewayTimeout = &APIError{HTTPStatus: http.StatusGatewayTimeout, Code: "BAD_GATEWAY_TIMEOUT", Message: "Bad gateway timeout"}
|
||||
ErrNoActiveKeys = &APIError{HTTPStatus: http.StatusServiceUnavailable, Code: "NO_ACTIVE_KEYS", Message: "No active API keys available for this group"}
|
||||
ErrMaxRetriesExceeded = &APIError{HTTPStatus: http.StatusBadGateway, Code: "MAX_RETRIES_EXCEEDED", Message: "Request failed after maximum retries"}
|
||||
ErrNoKeysAvailable = &APIError{HTTPStatus: http.StatusServiceUnavailable, Code: "NO_KEYS_AVAILABLE", Message: "No API keys available to process the request"}
|
||||
|
||||
@@ -37,6 +37,7 @@ var permanentErrorSubstrings = []string{
|
||||
"permission_denied", // Catches the 'status' field in Google's JSON error, e.g., "status": "PERMISSION_DENIED".
|
||||
"service_disabled", // Catches the 'reason' field for disabled APIs, e.g., "reason": "SERVICE_DISABLED".
|
||||
"api has not been used",
|
||||
"reported as leaked", // Leaked
|
||||
}
|
||||
|
||||
// --- 2. Temporary Errors ---
|
||||
@@ -44,8 +45,10 @@ var permanentErrorSubstrings = []string{
|
||||
// Action: Increment consecutive error count, potentially disable the key.
|
||||
var temporaryErrorSubstrings = []string{
|
||||
"quota",
|
||||
"Quota exceeded",
|
||||
"limit reached",
|
||||
"insufficient",
|
||||
"request limit",
|
||||
"billing",
|
||||
"exceeded",
|
||||
"too many requests",
|
||||
@@ -74,6 +77,24 @@ var clientNetworkErrorSubstrings = []string{
|
||||
"invalid query parameters", // 参数解析错误,归类为客户端错误
|
||||
}
|
||||
|
||||
// --- 5. Retryable Network/Gateway Errors ---
|
||||
// Errors that indicate temporary network or gateway issues, should retry with same or different key.
|
||||
// Action: Retry the request.
|
||||
var retryableNetworkErrorSubstrings = []string{
|
||||
"bad gateway",
|
||||
"service unavailable",
|
||||
"gateway timeout",
|
||||
"connection refused",
|
||||
"connection reset",
|
||||
"stream transmission interrupted", // ✅ 新增:流式传输中断
|
||||
"failed to establish stream", // ✅ 新增:流式连接建立失败
|
||||
"upstream connect error",
|
||||
"no healthy upstream",
|
||||
"502",
|
||||
"503",
|
||||
"504",
|
||||
}
|
||||
|
||||
// IsPermanentUpstreamError checks if an upstream error indicates the key is permanently invalid.
|
||||
func IsPermanentUpstreamError(msg string) bool {
|
||||
return containsSubstring(msg, permanentErrorSubstrings)
|
||||
@@ -97,6 +118,11 @@ func IsClientNetworkError(err error) bool {
|
||||
return containsSubstring(err.Error(), clientNetworkErrorSubstrings)
|
||||
}
|
||||
|
||||
// IsRetryableNetworkError checks if an error is a temporary network/gateway issue.
|
||||
func IsRetryableNetworkError(msg string) bool {
|
||||
return containsSubstring(msg, retryableNetworkErrorSubstrings)
|
||||
}
|
||||
|
||||
// containsSubstring is a helper function to avoid code repetition.
|
||||
func containsSubstring(s string, substrings []string) bool {
|
||||
if s == "" {
|
||||
|
||||
Reference in New Issue
Block a user