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{}{}
|
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 {
|
type AppError struct {
|
||||||
code int
|
code int
|
||||||
msg string
|
msg string
|
||||||
cause error
|
cause error
|
||||||
occurred string // 保存由底层错误导致AppErr发生时的位置
|
occurred string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *AppError) Error() 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
|
// 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 {
|
func (e *AppError) WithCause(err error) *AppError {
|
||||||
newErr := e.Clone()
|
newErr := e.Clone()
|
||||||
newErr.cause = err
|
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
|
// Wrap define func packaging information and errors returned by the underlying logic
|
||||||
// 用于逻辑中包装底层函数返回的error 和 WithCause 一样都是为了记录错误链条
|
|
||||||
// 该方法生成的error 用于日志记录, 返回响应请使用预定义好的error
|
|
||||||
func Wrap(msg string, err error) *AppError {
|
func Wrap(msg string, err error) *AppError {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -77,7 +71,7 @@ func (e *AppError) UnWrap() error {
|
||||||
return e.cause
|
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 {
|
func (e *AppError) Is(target error) bool {
|
||||||
targetErr, ok := target.(*AppError)
|
targetErr, ok := target.(*AppError)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -86,6 +80,17 @@ func (e *AppError) Is(target error) bool {
|
||||||
return targetErr.Code() == e.Code()
|
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
|
// Clone define func return a new AppError with source AppError's code, msg, cause, occurred
|
||||||
func (e *AppError) Clone() *AppError {
|
func (e *AppError) Clone() *AppError {
|
||||||
return &AppError{
|
return &AppError{
|
||||||
|
|
@ -107,7 +112,7 @@ func newError(code int, msg string) *AppError {
|
||||||
return &AppError{code: code, msg: msg}
|
return &AppError{code: code, msg: msg}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAppErrOccurredInfo 获取项目中调用Wrap或者WithCause方法时的程序位置, 方便排查问题
|
// getAppErrOccurredInfo define func return the location where the error is triggered
|
||||||
func getAppErrOccurredInfo() string {
|
func getAppErrOccurredInfo() string {
|
||||||
pc, file, line, ok := runtime.Caller(2)
|
pc, file, line, ok := runtime.Caller(2)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -140,7 +145,7 @@ type formattedErr struct {
|
||||||
Occurred string `json:"occurred"`
|
Occurred string `json:"occurred"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// toStructuredError 在JSON Encode 前把Error进行格式化
|
// toStructuredError define func convert AppError to structured error for better readability
|
||||||
func (e *AppError) toStructuredError() *formattedErr {
|
func (e *AppError) toStructuredError() *formattedErr {
|
||||||
fe := new(formattedErr)
|
fe := new(formattedErr)
|
||||||
fe.Code = e.Code()
|
fe.Code = e.Code()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue