You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
2.4 KiB
123 lines
2.4 KiB
package ecode |
|
|
|
import ( |
|
"fmt" |
|
"strconv" |
|
"sync/atomic" |
|
|
|
"github.com/pkg/errors" |
|
) |
|
|
|
var ( |
|
_messages atomic.Value // NOTE: stored map[string]map[int]string |
|
_codes = map[int]struct{}{} // register codes. |
|
) |
|
|
|
// Register register ecode message map. |
|
func Register(cm map[int]string) { |
|
_messages.Store(cm) |
|
} |
|
|
|
// New new a ecode.Codes by int value. |
|
// NOTE: ecode must unique in global, the New will check repeat and then panic. |
|
func New(e int) Code { |
|
if e <= 0 { |
|
panic("business ecode must greater than zero") |
|
} |
|
return add(e) |
|
} |
|
|
|
func add(e int) Code { |
|
if _, ok := _codes[e]; ok { |
|
panic(fmt.Sprintf("ecode: %d already exist", e)) |
|
} |
|
_codes[e] = struct{}{} |
|
return Int(e) |
|
} |
|
|
|
// Codes ecode error interface which has a code & message. |
|
type Codes interface { |
|
// sometimes Error return Code in string form |
|
// NOTE: don't use Error in monitor report even it also work for now |
|
Error() string |
|
// Code get error code. |
|
Code() int |
|
// Message get code message. |
|
Message() string |
|
//Detail get error detail,it may be nil. |
|
Details() []interface{} |
|
// Equal for compatible. |
|
// Deprecated: please use ecode.EqualError. |
|
Equal(error) bool |
|
} |
|
|
|
// A Code is an int error code spec. |
|
type Code int |
|
|
|
func (e Code) Error() string { |
|
return strconv.FormatInt(int64(e), 10) |
|
} |
|
|
|
// Code return error code |
|
func (e Code) Code() int { return int(e) } |
|
|
|
// Message return error message |
|
func (e Code) Message() string { |
|
if cm, ok := _messages.Load().(map[int]string); ok { |
|
if msg, ok := cm[e.Code()]; ok { |
|
return msg |
|
} |
|
} |
|
return e.Error() |
|
} |
|
|
|
// Details return details. |
|
func (e Code) Details() []interface{} { return nil } |
|
|
|
// Equal for compatible. |
|
// Deprecated: please use ecode.EqualError. |
|
func (e Code) Equal(err error) bool { return EqualError(e, err) } |
|
|
|
// Int parse code int to error. |
|
func Int(i int) Code { return Code(i) } |
|
|
|
// String parse code string to error. |
|
func String(e string) Code { |
|
if e == "" { |
|
return OK |
|
} |
|
// try error string |
|
i, err := strconv.Atoi(e) |
|
if err != nil { |
|
return ServerErr |
|
} |
|
return Code(i) |
|
} |
|
|
|
// Cause cause from error to ecode. |
|
func Cause(e error) Codes { |
|
if e == nil { |
|
return OK |
|
} |
|
ec, ok := errors.Cause(e).(Codes) |
|
if ok { |
|
return ec |
|
} |
|
return String(e.Error()) |
|
} |
|
|
|
// Equal equal a and b by code int. |
|
func Equal(a, b Codes) bool { |
|
if a == nil { |
|
a = OK |
|
} |
|
if b == nil { |
|
b = OK |
|
} |
|
return a.Code() == b.Code() |
|
} |
|
|
|
// EqualError equal error |
|
func EqualError(code Codes, err error) bool { |
|
return Cause(err).Code() == code.Code() |
|
}
|
|
|