error.go 1.4 KB

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