Update Js for logs.html
This commit is contained in:
@@ -2,7 +2,6 @@ package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -10,67 +9,37 @@ const (
|
||||
maxErrorBodyLength = 2048
|
||||
)
|
||||
|
||||
// standardErrorResponse matches formats like: {"error": {"message": "..."}}
|
||||
type standardErrorResponse struct {
|
||||
Error struct {
|
||||
Message string `json:"message"`
|
||||
} `json:"error"`
|
||||
}
|
||||
|
||||
// vendorErrorResponse matches formats like: {"error_msg": "..."}
|
||||
type vendorErrorResponse struct {
|
||||
ErrorMsg string `json:"error_msg"`
|
||||
}
|
||||
|
||||
// simpleErrorResponse matches formats like: {"error": "..."}
|
||||
type simpleErrorResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// rootMessageErrorResponse matches formats like: {"message": "..."}
|
||||
type rootMessageErrorResponse struct {
|
||||
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) string {
|
||||
// 1. Attempt to parse the standard OpenAI/Gemini format.
|
||||
var stdErr standardErrorResponse
|
||||
if err := json.Unmarshal(body, &stdErr); err == nil {
|
||||
if msg := strings.TrimSpace(stdErr.Error.Message); msg != "" {
|
||||
return truncateString(msg, maxErrorBodyLength)
|
||||
}
|
||||
func ParseUpstreamError(body []byte) (message string, status string) {
|
||||
if len(body) == 0 {
|
||||
return "Upstream returned an empty error body", ""
|
||||
}
|
||||
|
||||
// 2. Attempt to parse vendor-specific format (e.g., Baidu).
|
||||
var vendorErr vendorErrorResponse
|
||||
if err := json.Unmarshal(body, &vendorErr); err == nil {
|
||||
if msg := strings.TrimSpace(vendorErr.ErrorMsg); msg != "" {
|
||||
return truncateString(msg, maxErrorBodyLength)
|
||||
}
|
||||
// 优先级 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
|
||||
}
|
||||
|
||||
// 3. Attempt to parse simple error format.
|
||||
var simpleErr simpleErrorResponse
|
||||
if err := json.Unmarshal(body, &simpleErr); err == nil {
|
||||
if msg := strings.TrimSpace(simpleErr.Error); msg != "" {
|
||||
return truncateString(msg, maxErrorBodyLength)
|
||||
}
|
||||
// 优先级 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
|
||||
}
|
||||
|
||||
// 4. Attempt to parse root-level message format.
|
||||
var rootMsgErr rootMessageErrorResponse
|
||||
if err := json.Unmarshal(body, &rootMsgErr); err == nil {
|
||||
if msg := strings.TrimSpace(rootMsgErr.Message); msg != "" {
|
||||
return truncateString(msg, maxErrorBodyLength)
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Graceful Degradation: If all parsing fails, return the raw (but safe) body.
|
||||
return truncateString(string(body), maxErrorBodyLength)
|
||||
// 最终回退: 对于无法识别的 JSON 或纯文本错误
|
||||
return truncateString(string(body), maxErrorBodyLength), ""
|
||||
}
|
||||
|
||||
// truncateString ensures a string does not exceed a maximum length.
|
||||
// truncateString remains unchanged.
|
||||
func truncateString(s string, maxLength int) string {
|
||||
if len(s) > maxLength {
|
||||
return s[:maxLength]
|
||||
|
||||
Reference in New Issue
Block a user