package apierr import ( "encoding/json" "kpt-tmr-group/pkg/xerr" common "kpt-tmr-group/proto/go/backend/common" "net/http" "github.com/gin-gonic/gin" ) func New(code common.Error_Code) *Error { return &Error{err: &common.Error{ Code: code, Msg: errorMessage(code), }} } func errorMessage(code common.Error_Code) string { var errMessage string if msg, ok := common.Error_Code_name[int32(code)]; ok { errMessage = msg } else { errMessage = "INTERNAL_ERROR" } return errMessage } type Error struct { err *common.Error } func (e *Error) GetCode() common.Error_Code { return e.err.Code } func (e *Error) GetMsg() string { return e.err.Msg } func (e *Error) GetErrors() []string { return e.err.Errors } func (e *Error) Error() string { bs, _ := json.Marshal(e.err) return string(bs) } // Is 判断 err 和 e 是否相同 func (e *Error) Is(err error) bool { if gotErr, ok := err.(*Error); !ok { return false } else { return e.err.Code == gotErr.err.Code } } func (e *Error) MarshalJSON() ([]byte, error) { return json.Marshal(e.err) } func (e *Error) UnmarshalJSON(data []byte) error { var commonErr common.Error if err := json.Unmarshal(data, &commonErr); err != nil { return err } e.err = &commonErr return nil } func (e *Error) WithLocaleMessage(c *gin.Context) *Error { if msg := e.GetMsg(); msg != "" { return e.SetMessage(msg) } return e } func (e *Error) SetMessage(m string) *Error { e.err.Msg = m return e } func (e *Error) SetErrors(errMessages []string) *Error { e.err.Errors = errMessages return e } // With more information func (e *Error) With(errs ...error) *Error { for _, err := range errs { e.err.Errors = append(e.err.Errors, err.Error()) } return e } // WithContext return error with i18n message ? func WithContext(c *gin.Context, code common.Error_Code) *Error { return New(code).WithLocaleMessage(c) } // AbortError 用来处理多种内部错误. // 在复杂业务场景中,存在一个接口返回多种业务错误码情况,通过这个函数来统一处理 func AbortError(c *gin.Context, err error) { if err == nil { return } if e, ok := xerr.Cause(err).(*Error); ok { // 取默认状态码 statusCode := DefaultErrorStatusCode(e.err.Code) if !shouldIgnoreCode(statusCode) { c.Error(e) } c.AbortWithStatusJSON(statusCode, e.WithLocaleMessage(c)) return } c.Error(err) c.AbortWithStatusJSON(http.StatusInternalServerError, WithContext(c, common.Error_INTERNAL_ERROR).With(err)) } // AbortStatusError 用来处理多种内部错误和定制返回的 http status code. // 在复杂业务场景中,存在一个接口返回多种业务错误码情况,通过这个函数来统一处理 func AbortStatusError(c *gin.Context, httpCode int, err error) { if err == nil { return } if e, ok := xerr.Cause(err).(*Error); ok { c.Error(e) c.AbortWithStatusJSON(httpCode, WithContext(c, e.err.Code)) return } c.Error(err) c.AbortWithStatusJSON(httpCode, WithContext(c, common.Error_INTERNAL_ERROR).With(err)) } // DefaultErrorStatusCode 返回错误码对应的默认 http status code func DefaultErrorStatusCode(code common.Error_Code) int { if statusCode, ok := errorStatusCode[int(code)]; ok { return statusCode } return http.StatusInternalServerError } // 错误对应默认返回的 http status code var errorStatusCode = map[int]int{ 0: http.StatusOK, 10000: http.StatusUnauthorized, 11000: http.StatusBadRequest, 11001: http.StatusBadRequest, 11002: http.StatusBadRequest, 11003: http.StatusTooManyRequests, 11100: http.StatusBadRequest, 11200: http.StatusBadRequest, 20000: http.StatusBadRequest, 21000: http.StatusBadRequest, 22000: http.StatusBadRequest, 23000: http.StatusBadRequest, 23001: http.StatusBadRequest, 24000: http.StatusBadRequest, 24100: http.StatusBadRequest, 24101: http.StatusBadRequest, 24102: http.StatusBadRequest, 24103: http.StatusBadRequest, 24104: http.StatusBadRequest, 24400: http.StatusBadRequest, 24500: http.StatusBadRequest, 24501: http.StatusBadRequest, 24502: http.StatusBadRequest, 24520: http.StatusBadRequest, 24521: http.StatusBadRequest, 24522: http.StatusBadRequest, 24523: http.StatusBadRequest, 24524: http.StatusBadRequest, 24525: http.StatusBadRequest, 24526: http.StatusBadRequest, 24527: http.StatusBadRequest, 24528: http.StatusBadRequest, 24600: http.StatusBadRequest, 24601: http.StatusBadRequest, 24602: http.StatusBadRequest, 24603: http.StatusBadRequest, 24700: http.StatusBadRequest, 24701: http.StatusBadRequest, 24702: http.StatusBadRequest, 24704: http.StatusBadRequest, 24705: http.StatusBadRequest, 24706: http.StatusBadRequest, 24707: http.StatusBadRequest, 24800: http.StatusBadRequest, 24801: http.StatusBadRequest, 24802: http.StatusBadRequest, 24803: http.StatusBadRequest, 90000: http.StatusInternalServerError, 90100: http.StatusBadRequest, 90101: http.StatusBadRequest, 90102: http.StatusBadRequest, 91000: http.StatusInternalServerError, }