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 }