github.com/slackhq/nebula@v1.9.0/util/error.go (about) 1 package util 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/sirupsen/logrus" 8 ) 9 10 type ContextualError struct { 11 RealError error 12 Fields map[string]interface{} 13 Context string 14 } 15 16 func NewContextualError(msg string, fields map[string]interface{}, realError error) *ContextualError { 17 return &ContextualError{Context: msg, Fields: fields, RealError: realError} 18 } 19 20 // ContextualizeIfNeeded is a helper function to turn an error into a ContextualError if it is not already one 21 func ContextualizeIfNeeded(msg string, err error) error { 22 switch err.(type) { 23 case *ContextualError: 24 return err 25 default: 26 return NewContextualError(msg, nil, err) 27 } 28 } 29 30 // LogWithContextIfNeeded is a helper function to log an error line for an error or ContextualError 31 func LogWithContextIfNeeded(msg string, err error, l *logrus.Logger) { 32 switch v := err.(type) { 33 case *ContextualError: 34 v.Log(l) 35 default: 36 l.WithError(err).Error(msg) 37 } 38 } 39 40 func (ce *ContextualError) Error() string { 41 if ce.RealError == nil { 42 return ce.Context 43 } 44 return fmt.Errorf("%s (%v): %w", ce.Context, ce.Fields, ce.RealError).Error() 45 } 46 47 func (ce *ContextualError) Unwrap() error { 48 if ce.RealError == nil { 49 return errors.New(ce.Context) 50 } 51 return ce.RealError 52 } 53 54 func (ce *ContextualError) Log(lr *logrus.Logger) { 55 if ce.RealError != nil { 56 lr.WithFields(ce.Fields).WithError(ce.RealError).Error(ce.Context) 57 } else { 58 lr.WithFields(ce.Fields).Error(ce.Context) 59 } 60 }