package service import ( "encoding/json" "errors" "fmt" "io" "net/http" "one-api/common" "one-api/dto" "one-api/types" "strconv" "strings" ) func MidjourneyErrorWrapper(code int, desc string) *dto.MidjourneyResponse { return &dto.MidjourneyResponse{ Code: code, Description: desc, } } func MidjourneyErrorWithStatusCodeWrapper(code int, desc string, statusCode int) *dto.MidjourneyResponseWithStatusCode { return &dto.MidjourneyResponseWithStatusCode{ StatusCode: statusCode, Response: *MidjourneyErrorWrapper(code, desc), } } //// OpenAIErrorWrapper wraps an error into an OpenAIErrorWithStatusCode //func OpenAIErrorWrapper(err error, code string, statusCode int) *dto.OpenAIErrorWithStatusCode { // text := err.Error() // lowerText := strings.ToLower(text) // if !strings.HasPrefix(lowerText, "get file base64 from url") && !strings.HasPrefix(lowerText, "mime type is not supported") { // if strings.Contains(lowerText, "post") || strings.Contains(lowerText, "dial") || strings.Contains(lowerText, "http") { // common.SysLog(fmt.Sprintf("error: %s", text)) // text = "请求上游地址失败" // } // } // openAIError := dto.OpenAIError{ // Message: text, // Type: "new_api_error", // Code: code, // } // return &dto.OpenAIErrorWithStatusCode{ // Error: openAIError, // StatusCode: statusCode, // } //} // //func OpenAIErrorWrapperLocal(err error, code string, statusCode int) *dto.OpenAIErrorWithStatusCode { // openaiErr := OpenAIErrorWrapper(err, code, statusCode) // openaiErr.LocalError = true // return openaiErr //} func ClaudeErrorWrapper(err error, code string, statusCode int) *dto.ClaudeErrorWithStatusCode { text := err.Error() lowerText := strings.ToLower(text) if !strings.HasPrefix(lowerText, "get file base64 from url") { if strings.Contains(lowerText, "post") || strings.Contains(lowerText, "dial") || strings.Contains(lowerText, "http") { common.SysLog(fmt.Sprintf("error: %s", text)) text = "请求上游地址失败" } } claudeError := dto.ClaudeError{ Message: text, Type: "new_api_error", } return &dto.ClaudeErrorWithStatusCode{ Error: claudeError, StatusCode: statusCode, } } func ClaudeErrorWrapperLocal(err error, code string, statusCode int) *dto.ClaudeErrorWithStatusCode { claudeErr := ClaudeErrorWrapper(err, code, statusCode) claudeErr.LocalError = true return claudeErr } func RelayErrorHandler(resp *http.Response, showBodyWhenFail bool) (newApiErr *types.NewAPIError) { newApiErr = &types.NewAPIError{ StatusCode: resp.StatusCode, ErrorType: types.ErrorTypeOpenAIError, } responseBody, err := io.ReadAll(resp.Body) if err != nil { return } common.CloseResponseBodyGracefully(resp) var errResponse dto.GeneralErrorResponse err = common.Unmarshal(responseBody, &errResponse) if err != nil { if showBodyWhenFail { newApiErr.Err = fmt.Errorf("bad response status code %d, body: %s", resp.StatusCode, string(responseBody)) } else { newApiErr.Err = fmt.Errorf("bad response status code %d", resp.StatusCode) } return } if errResponse.Error.Message != "" { // General format error (OpenAI, Anthropic, Gemini, etc.) newApiErr = types.WithOpenAIError(errResponse.Error, resp.StatusCode) } else { newApiErr = types.NewErrorWithStatusCode(errors.New(errResponse.ToMessage()), types.ErrorCodeBadResponseStatusCode, resp.StatusCode) newApiErr.ErrorType = types.ErrorTypeOpenAIError } return } func ResetStatusCode(newApiErr *types.NewAPIError, statusCodeMappingStr string) { if statusCodeMappingStr == "" || statusCodeMappingStr == "{}" { return } statusCodeMapping := make(map[string]string) err := json.Unmarshal([]byte(statusCodeMappingStr), &statusCodeMapping) if err != nil { return } if newApiErr.StatusCode == http.StatusOK { return } codeStr := strconv.Itoa(newApiErr.StatusCode) if _, ok := statusCodeMapping[codeStr]; ok { intCode, _ := strconv.Atoi(statusCodeMapping[codeStr]) newApiErr.StatusCode = intCode } } func TaskErrorWrapperLocal(err error, code string, statusCode int) *dto.TaskError { openaiErr := TaskErrorWrapper(err, code, statusCode) openaiErr.LocalError = true return openaiErr } func TaskErrorWrapper(err error, code string, statusCode int) *dto.TaskError { text := err.Error() lowerText := strings.ToLower(text) if strings.Contains(lowerText, "post") || strings.Contains(lowerText, "dial") || strings.Contains(lowerText, "http") { common.SysLog(fmt.Sprintf("error: %s", text)) text = "请求上游地址失败" } //避免暴露内部错误 taskError := &dto.TaskError{ Code: code, Message: text, StatusCode: statusCode, Error: err, } return taskError }