diff --git a/controller/billing.go b/controller/billing.go index 1c92a2507..f75f68198 100644 --- a/controller/billing.go +++ b/controller/billing.go @@ -2,9 +2,9 @@ package controller import ( "github.com/QuantumNous/new-api/common" - "github.com/QuantumNous/new-api/dto" "github.com/QuantumNous/new-api/model" "github.com/QuantumNous/new-api/setting/operation_setting" + "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" ) @@ -29,7 +29,7 @@ func GetSubscription(c *gin.Context) { expiredTime = 0 } if err != nil { - openAIError := dto.OpenAIError{ + openAIError := types.OpenAIError{ Message: err.Error(), Type: "upstream_error", } @@ -81,7 +81,7 @@ func GetUsage(c *gin.Context) { quota, err = model.GetUserUsedQuota(userId) } if err != nil { - openAIError := dto.OpenAIError{ + openAIError := types.OpenAIError{ Message: err.Error(), Type: "new_api_error", } diff --git a/controller/model.go b/controller/model.go index c2409fc00..aa6c6e2b9 100644 --- a/controller/model.go +++ b/controller/model.go @@ -18,6 +18,7 @@ import ( "github.com/QuantumNous/new-api/service" "github.com/QuantumNous/new-api/setting/operation_setting" "github.com/QuantumNous/new-api/setting/ratio_setting" + "github.com/QuantumNous/new-api/types" "github.com/gin-gonic/gin" "github.com/samber/lo" ) @@ -275,7 +276,7 @@ func RetrieveModel(c *gin.Context, modelType int) { c.JSON(200, aiModel) } } else { - openAIError := dto.OpenAIError{ + openAIError := types.OpenAIError{ Message: fmt.Sprintf("The model '%s' does not exist", modelId), Type: "invalid_request_error", Param: "model", diff --git a/dto/error.go b/dto/error.go index 79547671b..cf00d6772 100644 --- a/dto/error.go +++ b/dto/error.go @@ -1,26 +1,31 @@ package dto -import "github.com/QuantumNous/new-api/types" +import ( + "encoding/json" -type OpenAIError struct { - Message string `json:"message"` - Type string `json:"type"` - Param string `json:"param"` - Code any `json:"code"` -} + "github.com/QuantumNous/new-api/common" + "github.com/QuantumNous/new-api/types" +) + +//type OpenAIError struct { +// Message string `json:"message"` +// Type string `json:"type"` +// Param string `json:"param"` +// Code any `json:"code"` +//} type OpenAIErrorWithStatusCode struct { - Error OpenAIError `json:"error"` - StatusCode int `json:"status_code"` + Error types.OpenAIError `json:"error"` + StatusCode int `json:"status_code"` LocalError bool } type GeneralErrorResponse struct { - Error types.OpenAIError `json:"error"` - Message string `json:"message"` - Msg string `json:"msg"` - Err string `json:"err"` - ErrorMsg string `json:"error_msg"` + Error json.RawMessage `json:"error"` + Message string `json:"message"` + Msg string `json:"msg"` + Err string `json:"err"` + ErrorMsg string `json:"error_msg"` Header struct { Message string `json:"message"` } `json:"header"` @@ -31,9 +36,35 @@ type GeneralErrorResponse struct { } `json:"response"` } +func (e GeneralErrorResponse) TryToOpenAIError() *types.OpenAIError { + var openAIError types.OpenAIError + if len(e.Error) > 0 { + err := common.Unmarshal(e.Error, &openAIError) + if err == nil && openAIError.Message != "" { + return &openAIError + } + } + return nil +} + func (e GeneralErrorResponse) ToMessage() string { - if e.Error.Message != "" { - return e.Error.Message + if len(e.Error) > 0 { + switch common.GetJsonType(e.Error) { + case "object": + var openAIError types.OpenAIError + err := common.Unmarshal(e.Error, &openAIError) + if err == nil && openAIError.Message != "" { + return openAIError.Message + } + case "string": + var msg string + err := common.Unmarshal(e.Error, &msg) + if err == nil && msg != "" { + return msg + } + default: + return string(e.Error) + } } if e.Message != "" { return e.Message diff --git a/relay/channel/zhipu_4v/dto.go b/relay/channel/zhipu_4v/dto.go index e5edd0ddf..e96feda6b 100644 --- a/relay/channel/zhipu_4v/dto.go +++ b/relay/channel/zhipu_4v/dto.go @@ -4,6 +4,7 @@ import ( "time" "github.com/QuantumNous/new-api/dto" + "github.com/QuantumNous/new-api/types" ) // type ZhipuMessage struct { @@ -37,7 +38,7 @@ type ZhipuV4Response struct { Model string `json:"model"` TextResponseChoices []dto.OpenAITextResponseChoice `json:"choices"` Usage dto.Usage `json:"usage"` - Error dto.OpenAIError `json:"error"` + Error types.OpenAIError `json:"error"` } // diff --git a/service/error.go b/service/error.go index 070335ec6..9e517e85a 100644 --- a/service/error.go +++ b/service/error.go @@ -96,19 +96,21 @@ func RelayErrorHandler(ctx context.Context, resp *http.Response, showBodyWhenFai if showBodyWhenFail { newApiErr.Err = fmt.Errorf("bad response status code %d, body: %s", resp.StatusCode, string(responseBody)) } else { - if common.DebugEnabled { - logger.LogInfo(ctx, fmt.Sprintf("bad response status code %d, body: %s", resp.StatusCode, string(responseBody))) - } + logger.LogError(ctx, fmt.Sprintf("bad response status code %d, body: %s", resp.StatusCode, string(responseBody))) newApiErr.Err = fmt.Errorf("bad response status code %d", resp.StatusCode) } return } - if errResponse.Error.Message != "" { + + if common.GetJsonType(errResponse.Error) == "object" { // General format error (OpenAI, Anthropic, Gemini, etc.) - newApiErr = types.WithOpenAIError(errResponse.Error, resp.StatusCode) - } else { - newApiErr = types.NewOpenAIError(errors.New(errResponse.ToMessage()), types.ErrorCodeBadResponseStatusCode, resp.StatusCode) + oaiError := errResponse.TryToOpenAIError() + if oaiError != nil { + newApiErr = types.WithOpenAIError(*oaiError, resp.StatusCode) + return + } } + newApiErr = types.NewOpenAIError(errors.New(errResponse.ToMessage()), types.ErrorCodeBadResponseStatusCode, resp.StatusCode) return }