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  }