56 lines
2.0 KiB
Go
56 lines
2.0 KiB
Go
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var providerErrorURL = regexp.MustCompile(`(?i)https?://[^\s<>"',。;)]+`)
|
|
var providerErrorSensitive = regexp.MustCompile(`(?i)余额|额度|配额|欠费|账单|充值|计费|密钥|密码|令牌|balance|quota|billing|credit|payment|funds|wallet|api[ _-]?key|authorization|bearer|cookie|(?:access|refresh|auth|session)[ _-]?token|token\s*[=:]|secret|password|credential|sk-[a-z0-9]|tenant|trace[ _-]?id|request[ _-]?id|internal stack|stack\s*trace|dial tcp|no such host|prompt\s*[=:]`)
|
|
|
|
// 只提取错误消息字段,不序列化整个响应,避免回传 headers、请求正文和诊断信息。
|
|
func providerErrorDetail(raw string) string {
|
|
raw = strings.TrimSpace(raw)
|
|
var payload any
|
|
if json.Unmarshal([]byte(raw), &payload) == nil {
|
|
raw = providerErrorMessageField(payload)
|
|
} else if strings.HasPrefix(raw, "{") || strings.HasPrefix(raw, "[") {
|
|
return ""
|
|
}
|
|
// 网关 HTML、敏感账务/凭据诊断整条隐藏;普通消息里的 URL 单独移除。
|
|
if strings.HasPrefix(raw, "{") || strings.HasPrefix(raw, "[") || strings.ContainsAny(raw, "<>") || providerErrorSensitive.MatchString(raw) {
|
|
return ""
|
|
}
|
|
raw = providerErrorURL.ReplaceAllString(raw, "[链接已隐藏]")
|
|
return truncateRunes(strings.Join(strings.Fields(raw), " "), 1_500)
|
|
}
|
|
|
|
func providerErrorMessageField(value any) string {
|
|
switch value := value.(type) {
|
|
case string:
|
|
return strings.TrimSpace(value)
|
|
case map[string]any:
|
|
for _, key := range []string{"error", "message", "msg", "detail"} {
|
|
if message := providerErrorMessageField(value[key]); message != "" {
|
|
return message
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func providerErrorWithDetail(fallback, raw string) string {
|
|
if message, ok := providerPayloadErrorCategory(raw); ok {
|
|
fallback = message
|
|
}
|
|
return appendProviderErrorDetail(fallback, raw)
|
|
}
|
|
|
|
func appendProviderErrorDetail(fallback, raw string) string {
|
|
if detail := providerErrorDetail(raw); detail != "" && detail != fallback {
|
|
return fallback + ";上游:" + detail
|
|
}
|
|
return fallback
|
|
}
|