diff --git a/common/errcode/code.go b/common/errcode/code.go deleted file mode 100644 index b462e8a..0000000 --- a/common/errcode/code.go +++ /dev/null @@ -1,73 +0,0 @@ -// Package errcode provides internal error definition and business error definition -package errcode - -import ( - "net/http" -) - -// 此处为公共的错误码, 预留 10000000 ~ 10000099 间的 100 个错误码 -var ( - Success = newError(0, "success") - ErrServer = newError(10000000, "服务器内部错误") - ErrParams = newError(10000001, "参数错误, 请检查") - ErrNotFound = newError(10000002, "资源未找到") - ErrPanic = newError(10000003, "(*^__^*)系统开小差了,请稍后重试") // 无预期的panic错误 - ErrToken = newError(10000004, "Token无效") - ErrForbidden = newError(10000005, "未授权") // 访问一些未授权的资源时的错误 - ErrTooManyRequests = newError(10000006, "请求过多") - ErrCoverData = newError(10000007, "ConvertDataError") // 数据转换错误 -) - -// 各个业务模块自定义的错误码, 从 10000100 开始, 可以按照不同的业务模块划分不同的号段 -// Example: -//var ( -// ErrOrderClosed = NewError(10000100, "订单已关闭") -//) - -// 用户模块相关错误码 10000100 ~ 1000199 -var ( - ErrUserInvalid = newError(10000101, "用户异常") - ErrUserNameOccupied = newError(10000102, "用户名已被占用") - ErrUserNotRight = newError(10000103, "用户名或密码不正确") -) - -// 商品模块相关错误码 10000200 ~ 1000299 -var ( - ErrCommodityNotExists = newError(10000200, "商品不存在") - ErrCommodityStockOut = newError(10000201, "库存不足") -) - -// 购物车模块相关错误码 10000300 ~ 1000399 -var ( - ErrCartItemParam = newError(10000300, "购物项参数异常") - ErrCartWrongUser = newError(10000301, "用户购物信息不匹配") -) - -// 订单模块相关错误码 10000500 ~ 10000599 -var ( - ErrOrderParams = newError(10000500, "订单参数异常") - ErrOrderCanNotBeChanged = newError(10000501, "订单不可修改") - ErrOrderUnsupportedPayScene = newError(10000502, "支付场景暂不支持") -) - -func (e *AppError) HttpStatusCode() int { - switch e.Code() { - case Success.Code(): - return http.StatusOK - case ErrServer.Code(), ErrPanic.Code(): - return http.StatusInternalServerError - case ErrParams.Code(), ErrUserInvalid.Code(), ErrUserNameOccupied.Code(), ErrUserNotRight.Code(), - ErrCommodityNotExists.Code(), ErrCommodityStockOut.Code(), ErrCartItemParam.Code(), ErrOrderParams.Code(): - return http.StatusBadRequest - case ErrNotFound.Code(): - return http.StatusNotFound - case ErrTooManyRequests.Code(): - return http.StatusTooManyRequests - case ErrToken.Code(): - return http.StatusUnauthorized - case ErrForbidden.Code(), ErrCartWrongUser.Code(), ErrOrderCanNotBeChanged.Code(): - return http.StatusForbidden - default: - return http.StatusInternalServerError - } -} diff --git a/common/errcode/error.go b/common/errcode/error.go index 04ec6bc..18eca89 100644 --- a/common/errcode/error.go +++ b/common/errcode/error.go @@ -10,12 +10,12 @@ import ( var codes = map[int]struct{}{} -// AppError define struct of internal error +// AppError define struct of internal error. occurred field records the location where the error is triggered type AppError struct { code int msg string cause error - occurred string // 保存由底层错误导致AppErr发生时的位置 + occurred string } func (e *AppError) Error() string { @@ -49,10 +49,6 @@ func (e *AppError) Cause() error { } // WithCause define func return top level predefined errors,where the cause field contains the underlying base error -// 在逻辑执行中出现错误, 比如dao层返回的数据库查询错误 -// 可以在领域层返回预定义的错误前附加上导致错误的基础错误。 -// 如果业务模块预定义的错误码比较详细, 可以使用这个方法, 反之错误码定义的比较笼统建议使用Wrap方法包装底层错误生成项目自定义Error -// 并将其记录到日志后再使用预定义错误码返回接口响应 func (e *AppError) WithCause(err error) *AppError { newErr := e.Clone() newErr.cause = err @@ -61,8 +57,6 @@ func (e *AppError) WithCause(err error) *AppError { } // Wrap define func packaging information and errors returned by the underlying logic -// 用于逻辑中包装底层函数返回的error 和 WithCause 一样都是为了记录错误链条 -// 该方法生成的error 用于日志记录, 返回响应请使用预定义好的error func Wrap(msg string, err error) *AppError { if err == nil { return nil @@ -77,7 +71,7 @@ func (e *AppError) UnWrap() error { return e.cause } -// Is define func return result of whether any error in err's tree matches target. implemented to support errors.Is(err, target) +// Is define func return result of whether any error in err's tree matches target. implemented to support errors.Is(err, target) func (e *AppError) Is(target error) bool { targetErr, ok := target.(*AppError) if !ok { @@ -86,6 +80,17 @@ func (e *AppError) Is(target error) bool { return targetErr.Code() == e.Code() } +// As define func return result of whether any error in err's tree matches target. implemented to support errors.As(err, target) +func (e *AppError) As(target any) bool { + t, ok := target.(**AppError) + if !ok { + return false + } + + *t = e + return true +} + // Clone define func return a new AppError with source AppError's code, msg, cause, occurred func (e *AppError) Clone() *AppError { return &AppError{ @@ -107,7 +112,7 @@ func newError(code int, msg string) *AppError { return &AppError{code: code, msg: msg} } -// getAppErrOccurredInfo 获取项目中调用Wrap或者WithCause方法时的程序位置, 方便排查问题 +// getAppErrOccurredInfo define func return the location where the error is triggered func getAppErrOccurredInfo() string { pc, file, line, ok := runtime.Caller(2) if !ok { @@ -140,7 +145,7 @@ type formattedErr struct { Occurred string `json:"occurred"` } -// toStructuredError 在JSON Encode 前把Error进行格式化 +// toStructuredError define func convert AppError to structured error for better readability func (e *AppError) toStructuredError() *formattedErr { fe := new(formattedErr) fe.Code = e.Code()