49 lines
1.5 KiB
Go
49 lines
1.5 KiB
Go
package errors
|
|
|
|
import (
|
|
"encoding/json"
|
|
)
|
|
|
|
const (
|
|
// maxErrorBodyLength defines the maximum length of an error message to be stored or returned.
|
|
maxErrorBodyLength = 2048
|
|
)
|
|
|
|
type upstreamErrorDetail struct {
|
|
Message string `json:"message"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
type upstreamErrorPayload struct {
|
|
Error upstreamErrorDetail `json:"error"`
|
|
}
|
|
|
|
// ParseUpstreamError attempts to parse a structured error message from an upstream response body
|
|
func ParseUpstreamError(body []byte) (message string, status string) {
|
|
if len(body) == 0 {
|
|
return "Upstream returned an empty error body", ""
|
|
}
|
|
// 优先级 1: 尝试解析 OpenAI 兼容接口返回的 `[{"error": {...}}]` 数组格式
|
|
var arrayPayload []upstreamErrorPayload
|
|
if err := json.Unmarshal(body, &arrayPayload); err == nil && len(arrayPayload) > 0 {
|
|
detail := arrayPayload[0].Error
|
|
return truncateString(detail.Message, maxErrorBodyLength), detail.Status
|
|
}
|
|
// 优先级 2: 尝试解析 Gemini 原生接口可能返回的 `{"error": {...}}` 单个对象格式
|
|
var singlePayload upstreamErrorPayload
|
|
if err := json.Unmarshal(body, &singlePayload); err == nil && singlePayload.Error.Message != "" {
|
|
detail := singlePayload.Error
|
|
return truncateString(detail.Message, maxErrorBodyLength), detail.Status
|
|
}
|
|
// 最终回退: 对于无法识别的 JSON 或纯文本错误
|
|
return truncateString(string(body), maxErrorBodyLength), ""
|
|
}
|
|
|
|
// truncateString remains unchanged.
|
|
func truncateString(s string, maxLength int) string {
|
|
if len(s) > maxLength {
|
|
return s[:maxLength]
|
|
}
|
|
return s
|
|
}
|