github.com/haraldrudell/parl@v0.4.176/g0/go-error.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package g0 7 8 import ( 9 "time" 10 11 "github.com/haraldrudell/parl" 12 "github.com/haraldrudell/parl/perrors" 13 "github.com/haraldrudell/parl/perrors/errorglue" 14 ) 15 16 // GoError is a wrapper around an error associating it with a Go goroutine 17 // and the situation in which this error occurred 18 type GoError struct { 19 err error // err is the underlying unadulteraded error. It is nil for non-fatal Go exits 20 t time.Time 21 errContext parl.GoErrorContext // errContext describes in what situation the error occured 22 g0 parl.Go // all errors are associated with a Go. 23 } 24 25 // NewGoError creates a GoError based on an error 26 func NewGoError(err error, errContext parl.GoErrorContext, g0 parl.Go) (goError parl.GoError) { 27 return &GoError{ 28 err: perrors.Stack(err), 29 t: time.Now(), 30 errContext: errContext, 31 g0: g0, 32 } 33 } 34 35 // Error returns a human-readable error message making GoError implement error 36 // - for nil errors, empty string is returned 37 func (e *GoError) Error() (message string) { 38 if e.err != nil { 39 message = e.err.Error() 40 } 41 return 42 } 43 44 // Time returns when the GoError was created 45 func (e *GoError) Time() (when time.Time) { 46 return e.t 47 } 48 49 // Err returns the underlying error 50 func (e *GoError) Err() (err error) { 51 return e.err 52 } 53 54 // ErrString returns string representation of error 55 // - if no error “OK” 56 // - if not debug or panic, short error with location 57 // - otherwise error with stack trace 58 func (e *GoError) ErrString() (errString string) { 59 var isLong = parl.IsThisDebug() 60 if !isLong { 61 isLong, _, _, _ = perrors.IsPanic(e) 62 } 63 if isLong { 64 errString = perrors.Long(e) 65 } else { 66 errString = perrors.Short(e) 67 } 68 return 69 } 70 71 func (e *GoError) IsThreadExit() (isThreadExit bool) { 72 return e.errContext == parl.GeExit || 73 e.errContext == parl.GePreDoneExit 74 } 75 76 func (e *GoError) IsFatal() (isThreadExit bool) { 77 return (e.errContext == parl.GeExit || 78 e.errContext == parl.GePreDoneExit) && 79 e.err != nil 80 } 81 82 func (e *GoError) ErrContext() (errContext parl.GoErrorContext) { 83 return e.errContext 84 } 85 86 func (e *GoError) Go() (g0 parl.Go) { 87 return e.g0 88 } 89 90 func (e *GoError) String() (s string) { 91 var err = e.err 92 var stack = errorglue.GetInnerMostStack(err) 93 if stack != nil { 94 s = "-at:" + stack.Frames()[0].String() 95 } 96 var message string 97 if err != nil { 98 message = perrors.Short(err) 99 } else { 100 message = "OK" 101 } 102 return "error:\x27" + message + "\x27context:" + e.errContext.String() + s 103 }