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  }