optimize code of custom error structure
This commit is contained in:
parent
e1886bc347
commit
13433f93e5
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue