github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/runtimer/callstack.go (about) 1 package runtimer 2 3 import ( 4 "fmt" 5 "runtime" 6 ) 7 8 type CallStack struct { 9 Func string 10 Line int 11 Err string 12 } 13 14 func (this *CallStack) ToString() string { 15 if len(this.Err) < 1 { 16 return fmt.Sprintf("{%v:%v}", this.Func, this.Line) 17 } 18 return fmt.Sprintf("{%v:%v|%v}", this.Func, this.Line, this.Err) 19 } 20 21 func GetCallStack(skip int, err error) *CallStack { 22 // skip: 0 => self 23 // skip: 1 => caller 24 // skip: 2 => caller's caller 25 pc, _, line, _ := runtime.Caller(skip) 26 p := runtime.FuncForPC(pc) 27 28 errStr := "" 29 if nil != err { 30 errStr = err.Error() 31 } 32 33 return &CallStack{p.Name(), line, errStr} 34 } 35 36 // MakeError 37 // @lastErr: should not be nil 38 // @newErr: could be nil 39 func MakeError(lastErr error, newErr error, skip int) error { 40 callstack := GetCallStack(skip, newErr) 41 return fmt.Errorf("%v|%v", callstack.ToString(), lastErr.Error()) 42 } 43 44 func AppendError(lastErr error, newErr error) error { 45 return MakeError(lastErr, newErr, 3) 46 } 47 48 func NewError(err error) error { 49 return MakeError(err, nil, 3) 50 }