gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/myx/errorx/error.go (about)

     1  package errorx
     2  
     3  import (
     4  	"gitee.com/zhongguo168a/gocodes/datax/convertx"
     5  	"gitee.com/zhongguo168a/gocodes/datax/mapx"
     6  	"sort"
     7  	"strings"
     8  )
     9  
    10  type Error struct {
    11  	error
    12  
    13  	ident string
    14  	args  map[string]interface{}
    15  }
    16  
    17  func (err *Error) Has(ident string) bool {
    18  	if err.ident == ident {
    19  		return true
    20  	}
    21  	if err.error != nil {
    22  		parent, ok := err.error.(*Error)
    23  		if ok {
    24  			return parent.Has(ident)
    25  		} else {
    26  			return strings.Contains(parent.Error(), ident)
    27  		}
    28  	}
    29  	return false
    30  }
    31  
    32  // Error 最终形成字符串:ident?key=value&key2=value2
    33  func (err *Error) Error() (r string) {
    34  	cur := err
    35  	r = createMessage(cur.ident, cur.args)
    36  	for {
    37  		if cur.error == nil {
    38  			break
    39  		}
    40  		next, ok := cur.error.(*Error)
    41  		if !ok {
    42  			r += ": " + cur.error.Error()
    43  			break
    44  		}
    45  		r += ": " + createMessage(next.ident, next.args)
    46  		//
    47  		cur = next
    48  	}
    49  	return
    50  }
    51  
    52  // Ident 指定的 ident 用于识别错误的类型。
    53  func (err *Error) Ident() string {
    54  	return err.ident
    55  }
    56  
    57  // Args 指定的 args 按照约定格式编写,便于与 ident 分离,更容易的判断错误类型。
    58  // 可通过 mapx 包获取错误时输入的参数
    59  func (err *Error) Args() map[string]interface{} {
    60  	return err.args
    61  }
    62  
    63  // New 新建一个错误。
    64  // args只保存第一个元素
    65  func New(ident string, args ...map[string]interface{}) error {
    66  	e := &Error{
    67  		error: nil,
    68  		ident: ident,
    69  	}
    70  
    71  	if len(args) > 0 {
    72  		e.args = args[0]
    73  	}
    74  
    75  	return e
    76  }
    77  
    78  // Wrap 包装一个错误。
    79  // args只保存第一个元素
    80  func Wrap(err error, ident string, args ...map[string]interface{}) error {
    81  	if err == nil {
    82  		return New("wrap err is nil", map[string]interface{}{
    83  			"ident": ident,
    84  		})
    85  	}
    86  	e := &Error{
    87  		error: err,
    88  		ident: ident,
    89  	}
    90  
    91  	if len(args) > 0 {
    92  		e.args = args[0]
    93  	}
    94  
    95  	return e
    96  }
    97  
    98  func createMessage(ident string, args map[string]interface{}) string {
    99  	var argstr = ""
   100  	if args != nil {
   101  		var arr []string
   102  		keys := mapx.Keys(args)
   103  		sort.Strings(keys)
   104  		for _, mkey := range keys {
   105  			mval := args[mkey]
   106  			arr = append(arr, mkey+"="+convertx.AnyToString(mval))
   107  		}
   108  		argstr = "?" + strings.Join(arr, "&")
   109  	}
   110  
   111  	return ident + argstr
   112  }
   113  
   114  func Has(err error, ident string) bool {
   115  	if err != nil {
   116  		parent, ok := err.(*Error)
   117  		if ok {
   118  			return parent.Has(ident)
   119  		} else {
   120  			return strings.Contains(parent.Error(), ident)
   121  		}
   122  	}
   123  	return false
   124  }