123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- 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()
- }
|