github.com/sandwich-go/boost@v1.3.29/xerror/xerror_error.go (about)

     1  package xerror
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"runtime"
     7  	"strings"
     8  )
     9  
    10  var (
    11  	ErrorCodeOk              int32 = 0
    12  	ErrorCodeUnsetAsDefault  int32 = 1
    13  	goRootForFilter                = runtime.GOROOT()
    14  	CodeHandlerForNotAPICode       = func(err error) int32 {
    15  		if err == nil {
    16  			return ErrorCodeOk
    17  		}
    18  		return ErrorCodeUnsetAsDefault
    19  	}
    20  )
    21  
    22  func init() {
    23  	goRootForFilter = strings.Replace(goRootForFilter, "\\", "/", -1)
    24  }
    25  
    26  var _ APICode = &Error{}
    27  var _ apiStack = &Error{}
    28  var _ apiCause = &Error{}
    29  
    30  // Error 实现error接口,返回所有的错误信息,text: error具体数据
    31  func (cc *Error) Error() string {
    32  	if cc == nil {
    33  		return ""
    34  	}
    35  	errStr := cc.text
    36  	if cc.err != nil {
    37  		if cc.text != "" {
    38  			errStr += ": "
    39  		}
    40  		errStr += cc.err.Error()
    41  	}
    42  	return errStr
    43  }
    44  
    45  // Code 返回错误码,如果Error为nil,则根据CodeHandlerForNotAPICode逻辑返回
    46  func (cc *Error) Code() int32 {
    47  	if cc == nil {
    48  		// 注意这里使用nil作为error接口的输入值,不要使用cc引起接口类型不为空但是值为空的问题
    49  		return CodeHandlerForNotAPICode(nil)
    50  	}
    51  	return cc.code
    52  }
    53  
    54  // Cause 返回错误的起因
    55  func (cc *Error) Cause() error {
    56  	if cc == nil {
    57  		return nil
    58  	}
    59  	loop := cc
    60  	for loop != nil {
    61  		if loop.err != nil {
    62  			if e, ok := loop.err.(*Error); ok {
    63  				loop = e
    64  			} else if ac, ok0 := loop.err.(apiCause); ok0 {
    65  				return ac.Cause()
    66  			} else {
    67  				return loop.err
    68  			}
    69  		} else {
    70  			// 直接返回最初的error对象
    71  			return loop
    72  		}
    73  	}
    74  	return nil
    75  }
    76  
    77  // Format formats the frame according to the fmt.Formatter interface.
    78  // %s,%v 全部错误信息
    79  // %-s,%-v 当前错误信息
    80  // %+v,%+s 错误字符串 + stack信息
    81  func (cc *Error) Format(s fmt.State, verb rune) {
    82  	switch verb {
    83  	case 's', 'v':
    84  		switch {
    85  		case s.Flag('-'):
    86  			if cc.text != "" {
    87  				_, _ = io.WriteString(s, cc.text)
    88  			} else {
    89  				_, _ = io.WriteString(s, cc.Error())
    90  			}
    91  		case s.Flag('+'):
    92  			_, _ = io.WriteString(s, cc.Error()+"\n"+cc.Stack())
    93  		default:
    94  			_, _ = io.WriteString(s, cc.Error())
    95  		}
    96  	}
    97  }