package fserr import ( "fmt" "github.com/pkg/errors" "io" ) const ( ErrUnknownCode uint32 = 0x00000001 ErrParamCode uint32 = 0x00000002 ErrConflictCode uint32 = 0x00000003 ErrNotExistCode uint32 = 0x00000004 ErrTypeTransferCode uint32 = 0x00000005 ErrAuthCode uint32 = 0x00000006 ErrDataCode uint32 = 0x00000007 ErrCustomCode uint32 = 0x00001000 ) var codeMap = map[uint32]string{ ErrUnknownCode: "未知错误", ErrParamCode: "参数错误", ErrConflictCode: "资源冲突", ErrNotExistCode: "资源不存在", ErrTypeTransferCode: "类型转换错误", ErrAuthCode: "鉴权错误", ErrDataCode: "数据异常", ErrCustomCode: "自定义错误", } func ExplainCode(code uint32) string { explain, ok := codeMap[code] if !ok { return codeMap[ErrUnknownCode] } return explain } func TransferFromError(err error) *Error { transferErr, ok := err.(*Error) if ok { return transferErr } return NewUnknownError(err.Error()) } func NewError(code uint32, message string) *Error { return newError(code, message) } func NewUnknownError(message string) *Error { return newError(ErrUnknownCode, message) } func NewParamError(message string) *Error { return newError(ErrParamCode, message) } func NewConflictError(message string) *Error { return newError(ErrConflictCode, message) } func NewNotExistError(message string) *Error { return newError(ErrNotExistCode, message) } func NewTypeTransferError(message string) *Error { return newError(ErrTypeTransferCode, message) } func NewAuthError(message string) *Error { return newError(ErrAuthCode, message) } func NewDataError(message string) *Error { return newError(ErrDataCode, message) } func NewCustomError(message string) *Error { return newError(ErrCustomCode, message) } type Error struct { code uint32 message string StackMessage string } func (err *Error) Code() uint32 { return err.code } func (err *Error) Error() string { return err.message } func (err *Error) WithStack() error { return &Error{ code: err.code, message: err.message, StackMessage: formStackMessage(err.message), } } func (err *Error) Is(target error) bool { transferErr, ok := target.(*Error) if !ok { return false } return err.message == transferErr.message && err.code == transferErr.code } func (err *Error) Format(s fmt.State, verb rune) { switch verb { case 'v': if s.Flag('+') { io.WriteString(s, err.StackMessage) return } fallthrough case 's': io.WriteString(s, err.message) case 'q': fmt.Fprintf(s, "%q", err.message) } } func newError(code uint32, message string) *Error { _, ok := codeMap[code] if !ok { code = ErrUnknownCode } return &Error{ code: code, message: message, StackMessage: formStackMessage(message), } } func formStackMessage(message string) string { return fmt.Sprintf("\n%+v\n", errors.New(message)) }