You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

414 lines
10 KiB

  1. package types
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "strings"
  8. "github.com/QuantumNous/new-api/common"
  9. )
  10. type OpenAIError struct {
  11. Message string `json:"message"`
  12. Type string `json:"type"`
  13. Param string `json:"param"`
  14. Code any `json:"code"`
  15. Metadata json.RawMessage `json:"metadata,omitempty"`
  16. }
  17. type ClaudeError struct {
  18. Type string `json:"type,omitempty"`
  19. Message string `json:"message,omitempty"`
  20. }
  21. type ErrorType string
  22. const (
  23. ErrorTypeNewAPIError ErrorType = "new_api_error"
  24. ErrorTypeOpenAIError ErrorType = "openai_error"
  25. ErrorTypeClaudeError ErrorType = "claude_error"
  26. ErrorTypeMidjourneyError ErrorType = "midjourney_error"
  27. ErrorTypeGeminiError ErrorType = "gemini_error"
  28. ErrorTypeRerankError ErrorType = "rerank_error"
  29. ErrorTypeUpstreamError ErrorType = "upstream_error"
  30. )
  31. type ErrorCode string
  32. const (
  33. ErrorCodeInvalidRequest ErrorCode = "invalid_request"
  34. ErrorCodeSensitiveWordsDetected ErrorCode = "sensitive_words_detected"
  35. ErrorCodeViolationFeeGrokCSAM ErrorCode = "violation_fee.grok.csam"
  36. // new api error
  37. ErrorCodeCountTokenFailed ErrorCode = "count_token_failed"
  38. ErrorCodeModelPriceError ErrorCode = "model_price_error"
  39. ErrorCodeInvalidApiType ErrorCode = "invalid_api_type"
  40. ErrorCodeJsonMarshalFailed ErrorCode = "json_marshal_failed"
  41. ErrorCodeDoRequestFailed ErrorCode = "do_request_failed"
  42. ErrorCodeGetChannelFailed ErrorCode = "get_channel_failed"
  43. ErrorCodeGenRelayInfoFailed ErrorCode = "gen_relay_info_failed"
  44. // channel error
  45. ErrorCodeChannelNoAvailableKey ErrorCode = "channel:no_available_key"
  46. ErrorCodeChannelParamOverrideInvalid ErrorCode = "channel:param_override_invalid"
  47. ErrorCodeChannelHeaderOverrideInvalid ErrorCode = "channel:header_override_invalid"
  48. ErrorCodeChannelModelMappedError ErrorCode = "channel:model_mapped_error"
  49. ErrorCodeChannelAwsClientError ErrorCode = "channel:aws_client_error"
  50. ErrorCodeChannelInvalidKey ErrorCode = "channel:invalid_key"
  51. ErrorCodeChannelResponseTimeExceeded ErrorCode = "channel:response_time_exceeded"
  52. // client request error
  53. ErrorCodeReadRequestBodyFailed ErrorCode = "read_request_body_failed"
  54. ErrorCodeConvertRequestFailed ErrorCode = "convert_request_failed"
  55. ErrorCodeAccessDenied ErrorCode = "access_denied"
  56. // request error
  57. ErrorCodeBadRequestBody ErrorCode = "bad_request_body"
  58. // response error
  59. ErrorCodeReadResponseBodyFailed ErrorCode = "read_response_body_failed"
  60. ErrorCodeBadResponseStatusCode ErrorCode = "bad_response_status_code"
  61. ErrorCodeBadResponse ErrorCode = "bad_response"
  62. ErrorCodeBadResponseBody ErrorCode = "bad_response_body"
  63. ErrorCodeEmptyResponse ErrorCode = "empty_response"
  64. ErrorCodeAwsInvokeError ErrorCode = "aws_invoke_error"
  65. ErrorCodeModelNotFound ErrorCode = "model_not_found"
  66. ErrorCodePromptBlocked ErrorCode = "prompt_blocked"
  67. // sql error
  68. ErrorCodeQueryDataError ErrorCode = "query_data_error"
  69. ErrorCodeUpdateDataError ErrorCode = "update_data_error"
  70. // quota error
  71. ErrorCodeInsufficientUserQuota ErrorCode = "insufficient_user_quota"
  72. ErrorCodePreConsumeTokenQuotaFailed ErrorCode = "pre_consume_token_quota_failed"
  73. )
  74. type NewAPIError struct {
  75. Err error
  76. RelayError any
  77. skipRetry bool
  78. recordErrorLog *bool
  79. errorType ErrorType
  80. errorCode ErrorCode
  81. StatusCode int
  82. Metadata json.RawMessage
  83. UpstreamRequestId string
  84. UpstreamBody string
  85. }
  86. // Unwrap enables errors.Is / errors.As to work with NewAPIError by exposing the underlying error.
  87. func (e *NewAPIError) Unwrap() error {
  88. if e == nil {
  89. return nil
  90. }
  91. return e.Err
  92. }
  93. func (e *NewAPIError) GetErrorCode() ErrorCode {
  94. if e == nil {
  95. return ""
  96. }
  97. return e.errorCode
  98. }
  99. func (e *NewAPIError) GetErrorType() ErrorType {
  100. if e == nil {
  101. return ""
  102. }
  103. return e.errorType
  104. }
  105. func (e *NewAPIError) Error() string {
  106. if e == nil {
  107. return ""
  108. }
  109. if e.Err == nil {
  110. // fallback message when underlying error is missing
  111. return string(e.errorCode)
  112. }
  113. return e.Err.Error()
  114. }
  115. func (e *NewAPIError) ErrorWithStatusCode() string {
  116. if e == nil {
  117. return ""
  118. }
  119. msg := e.Error()
  120. if e.StatusCode == 0 {
  121. return msg
  122. }
  123. if msg == "" {
  124. return fmt.Sprintf("status_code=%d", e.StatusCode)
  125. }
  126. return fmt.Sprintf("status_code=%d, %s", e.StatusCode, msg)
  127. }
  128. func (e *NewAPIError) MaskSensitiveError() string {
  129. if e == nil {
  130. return ""
  131. }
  132. if e.Err == nil {
  133. return string(e.errorCode)
  134. }
  135. errStr := e.Err.Error()
  136. if e.errorCode == ErrorCodeCountTokenFailed {
  137. return errStr
  138. }
  139. return common.MaskSensitiveInfo(errStr)
  140. }
  141. func (e *NewAPIError) MaskSensitiveErrorWithStatusCode() string {
  142. if e == nil {
  143. return ""
  144. }
  145. msg := e.MaskSensitiveError()
  146. if e.StatusCode == 0 {
  147. return msg
  148. }
  149. if msg == "" {
  150. return fmt.Sprintf("status_code=%d", e.StatusCode)
  151. }
  152. return fmt.Sprintf("status_code=%d, %s", e.StatusCode, msg)
  153. }
  154. func (e *NewAPIError) SetMessage(message string) {
  155. e.Err = errors.New(message)
  156. }
  157. func (e *NewAPIError) ToOpenAIError() OpenAIError {
  158. var result OpenAIError
  159. switch e.errorType {
  160. case ErrorTypeOpenAIError:
  161. if openAIError, ok := e.RelayError.(OpenAIError); ok {
  162. result = openAIError
  163. }
  164. case ErrorTypeClaudeError:
  165. if claudeError, ok := e.RelayError.(ClaudeError); ok {
  166. result = OpenAIError{
  167. Message: e.Error(),
  168. Type: claudeError.Type,
  169. Param: "",
  170. Code: e.errorCode,
  171. }
  172. }
  173. default:
  174. result = OpenAIError{
  175. Message: e.Error(),
  176. Type: string(e.errorType),
  177. Param: "",
  178. Code: e.errorCode,
  179. }
  180. }
  181. if e.errorCode != ErrorCodeCountTokenFailed {
  182. result.Message = common.MaskSensitiveInfo(result.Message)
  183. }
  184. if result.Message == "" {
  185. result.Message = string(e.errorType)
  186. }
  187. return result
  188. }
  189. func (e *NewAPIError) ToClaudeError() ClaudeError {
  190. var result ClaudeError
  191. switch e.errorType {
  192. case ErrorTypeOpenAIError:
  193. if openAIError, ok := e.RelayError.(OpenAIError); ok {
  194. result = ClaudeError{
  195. Message: e.Error(),
  196. Type: fmt.Sprintf("%v", openAIError.Code),
  197. }
  198. }
  199. case ErrorTypeClaudeError:
  200. if claudeError, ok := e.RelayError.(ClaudeError); ok {
  201. result = claudeError
  202. }
  203. default:
  204. result = ClaudeError{
  205. Message: e.Error(),
  206. Type: string(e.errorType),
  207. }
  208. }
  209. if e.errorCode != ErrorCodeCountTokenFailed {
  210. result.Message = common.MaskSensitiveInfo(result.Message)
  211. }
  212. if result.Message == "" {
  213. result.Message = string(e.errorType)
  214. }
  215. return result
  216. }
  217. type NewAPIErrorOptions func(*NewAPIError)
  218. func NewError(err error, errorCode ErrorCode, ops ...NewAPIErrorOptions) *NewAPIError {
  219. var newErr *NewAPIError
  220. // 保留深层传递的 new err
  221. if errors.As(err, &newErr) {
  222. for _, op := range ops {
  223. op(newErr)
  224. }
  225. return newErr
  226. }
  227. e := &NewAPIError{
  228. Err: err,
  229. RelayError: nil,
  230. errorType: ErrorTypeNewAPIError,
  231. StatusCode: http.StatusInternalServerError,
  232. errorCode: errorCode,
  233. }
  234. for _, op := range ops {
  235. op(e)
  236. }
  237. return e
  238. }
  239. func NewOpenAIError(err error, errorCode ErrorCode, statusCode int, ops ...NewAPIErrorOptions) *NewAPIError {
  240. var newErr *NewAPIError
  241. // 保留深层传递的 new err
  242. if errors.As(err, &newErr) {
  243. if newErr.RelayError == nil {
  244. openaiError := OpenAIError{
  245. Message: newErr.Error(),
  246. Type: string(errorCode),
  247. Code: errorCode,
  248. }
  249. newErr.RelayError = openaiError
  250. }
  251. for _, op := range ops {
  252. op(newErr)
  253. }
  254. return newErr
  255. }
  256. openaiError := OpenAIError{
  257. Message: err.Error(),
  258. Type: string(errorCode),
  259. Code: errorCode,
  260. }
  261. return WithOpenAIError(openaiError, statusCode, ops...)
  262. }
  263. func InitOpenAIError(errorCode ErrorCode, statusCode int, ops ...NewAPIErrorOptions) *NewAPIError {
  264. openaiError := OpenAIError{
  265. Type: string(errorCode),
  266. Code: errorCode,
  267. }
  268. return WithOpenAIError(openaiError, statusCode, ops...)
  269. }
  270. func NewErrorWithStatusCode(err error, errorCode ErrorCode, statusCode int, ops ...NewAPIErrorOptions) *NewAPIError {
  271. e := &NewAPIError{
  272. Err: err,
  273. RelayError: OpenAIError{
  274. Message: err.Error(),
  275. Type: string(errorCode),
  276. },
  277. errorType: ErrorTypeNewAPIError,
  278. StatusCode: statusCode,
  279. errorCode: errorCode,
  280. }
  281. for _, op := range ops {
  282. op(e)
  283. }
  284. return e
  285. }
  286. func WithOpenAIError(openAIError OpenAIError, statusCode int, ops ...NewAPIErrorOptions) *NewAPIError {
  287. code, ok := openAIError.Code.(string)
  288. if !ok {
  289. if openAIError.Code != nil {
  290. code = fmt.Sprintf("%v", openAIError.Code)
  291. } else {
  292. code = "unknown_error"
  293. }
  294. }
  295. if openAIError.Type == "" {
  296. openAIError.Type = "upstream_error"
  297. }
  298. e := &NewAPIError{
  299. RelayError: openAIError,
  300. errorType: ErrorTypeOpenAIError,
  301. StatusCode: statusCode,
  302. Err: errors.New(openAIError.Message),
  303. errorCode: ErrorCode(code),
  304. }
  305. // OpenRouter
  306. if len(openAIError.Metadata) > 0 {
  307. openAIError.Message = fmt.Sprintf("%s (%s)", openAIError.Message, openAIError.Metadata)
  308. e.Metadata = openAIError.Metadata
  309. e.RelayError = openAIError
  310. e.Err = errors.New(openAIError.Message)
  311. }
  312. for _, op := range ops {
  313. op(e)
  314. }
  315. return e
  316. }
  317. func WithClaudeError(claudeError ClaudeError, statusCode int, ops ...NewAPIErrorOptions) *NewAPIError {
  318. if claudeError.Type == "" {
  319. claudeError.Type = "upstream_error"
  320. }
  321. e := &NewAPIError{
  322. RelayError: claudeError,
  323. errorType: ErrorTypeClaudeError,
  324. StatusCode: statusCode,
  325. Err: errors.New(claudeError.Message),
  326. errorCode: ErrorCode(claudeError.Type),
  327. }
  328. for _, op := range ops {
  329. op(e)
  330. }
  331. return e
  332. }
  333. func IsChannelError(err *NewAPIError) bool {
  334. if err == nil {
  335. return false
  336. }
  337. return strings.HasPrefix(string(err.errorCode), "channel:")
  338. }
  339. func IsSkipRetryError(err *NewAPIError) bool {
  340. if err == nil {
  341. return false
  342. }
  343. return err.skipRetry
  344. }
  345. func ErrOptionWithSkipRetry() NewAPIErrorOptions {
  346. return func(e *NewAPIError) {
  347. e.skipRetry = true
  348. }
  349. }
  350. func ErrOptionWithNoRecordErrorLog() NewAPIErrorOptions {
  351. return func(e *NewAPIError) {
  352. e.recordErrorLog = common.GetPointer(false)
  353. }
  354. }
  355. func ErrOptionWithHideErrMsg(replaceStr string) NewAPIErrorOptions {
  356. return func(e *NewAPIError) {
  357. if common.DebugEnabled {
  358. fmt.Printf("ErrOptionWithHideErrMsg: %s, origin error: %s", replaceStr, e.Err)
  359. }
  360. e.Err = errors.New(replaceStr)
  361. }
  362. }
  363. func IsRecordErrorLog(e *NewAPIError) bool {
  364. if e == nil {
  365. return false
  366. }
  367. if e.recordErrorLog == nil {
  368. // default to true if not set
  369. return true
  370. }
  371. return *e.recordErrorLog
  372. }