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  }