gitlab.nesad.fit.vutbr.cz/blended/libblended@v0.0.0-20221202124402-2bee159339df/errors/errors.go (about)

     1  // Blended: Errors handling package
     2  // Based on pkg/errors and henrmota/errors-handling-example
     3  // Dominika Regeciova, FIT BUT
     4  
     5  package errors
     6  
     7  import (
     8  	"fmt"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  // Additional information: the type of an error
    13  type ErrorType uint8
    14  
    15  const (
    16  	// NoType error
    17  	NoType ErrorType = iota
    18  	// Ethereum error
    19  	EthereumError
    20  	// Collector error
    21  	CollectorError
    22  	// Runner error
    23  	RunnerError
    24  	// API interface error
    25  	APIError
    26  	// IPFS error
    27  	IpfsError
    28  	// Catalog error
    29  	CatalogError
    30  )
    31  
    32  type blendedError struct {
    33  	errorType     ErrorType
    34  	originalError error
    35  	context       errorContext
    36  }
    37  
    38  type errorContext struct {
    39  	Field   string
    40  	Message string
    41  }
    42  
    43  // New creates a no type error
    44  func New(msg string) error {
    45  	return blendedError{errorType: NoType, originalError: errors.New(msg)}
    46  }
    47  
    48  // Newf creates a no type error with formatted message
    49  func Newf(msg string, args ...interface{}) error {
    50  	return blendedError{errorType: NoType, originalError: errors.New(fmt.Sprintf(msg, args...))}
    51  }
    52  
    53  // New creates a new blendedError
    54  func (errorType ErrorType) New(msg string) error {
    55  	return blendedError{errorType: errorType, originalError: errors.New(msg)}
    56  }
    57  
    58  // New creates a new blendedError with formatted message
    59  func (errorType ErrorType) Newf(msg string, args ...interface{}) error {
    60  	return blendedError{errorType: errorType, originalError: fmt.Errorf(msg, args...)}
    61  }
    62  
    63  // Wrap an error with a string
    64  // If err is nil, Wrapf returns nil.
    65  func Wrap(err error, msg string) error {
    66  	if err == nil {
    67  		return nil
    68  	}
    69  	return Wrapf(err, msg)
    70  }
    71  
    72  // Wrapf an error with format string
    73  // If err is nil, Wrapf returns nil.
    74  func Wrapf(err error, msg string, args ...interface{}) error {
    75  	wrappedError := errors.Wrapf(err, msg, args...)
    76  	if blendedErr, ok := err.(blendedError); ok {
    77  		return blendedError{
    78  			errorType:     blendedErr.errorType,
    79  			originalError: wrappedError,
    80  			context:       blendedErr.context,
    81  		}
    82  	}
    83  
    84  	return blendedError{errorType: NoType, originalError: wrappedError}
    85  }
    86  
    87  // Wrap creates a new wrapped error
    88  // If err is nil, Wrapf returns nil.
    89  func (errorType ErrorType) Wrap(err error, msg string) error {
    90  	if err == nil {
    91  		return nil
    92  	}
    93  	//return errorType.Wrapf(err, msg)
    94  	return blendedError{errorType: errorType, originalError: errors.Wrap(err, msg)}
    95  }
    96  
    97  // Wrap creates a new wrapped error with formatted message
    98  // If err is nil, Wrapf returns nil.
    99  func (errorType ErrorType) Wrapf(err error, msg string, args ...interface{}) error {
   100  	if err == nil {
   101  		return nil
   102  	}
   103  	return blendedError{errorType: errorType, originalError: errors.Wrapf(err, msg, args...)}
   104  }
   105  
   106  // Error returns the message of a blendedError
   107  func (error blendedError) Error() string {
   108  	return error.originalError.Error()
   109  }
   110  
   111  // Cause gives the original error
   112  func Cause(err error) error {
   113  	return errors.Cause(GetOriginalError(err))
   114  }
   115  
   116  // AddErrorContext adds a context to an error
   117  func AddErrorContext(err error, field, message string) error {
   118  	context := errorContext{Field: field, Message: message}
   119  	if blendedErr, ok := err.(blendedError); ok {
   120  		return blendedError{errorType: blendedErr.errorType, originalError: blendedErr.originalError, context: context}
   121  	}
   122  
   123  	return blendedError{errorType: NoType, originalError: err, context: context}
   124  }
   125  
   126  // GetErrorContext returns the error context
   127  func GetErrorContext(err error) map[string]string {
   128  	emptyContext := errorContext{}
   129  	if blendedErr, ok := err.(blendedError); ok || blendedErr.context != emptyContext {
   130  
   131  		return map[string]string{"field": blendedErr.context.Field, "message": blendedErr.context.Message}
   132  	}
   133  
   134  	return nil
   135  }
   136  
   137  // GetType returns the error type
   138  func GetType(err error) ErrorType {
   139  	if blendedErr, ok := err.(blendedError); ok {
   140  		return blendedErr.errorType
   141  	}
   142  
   143  	return NoType
   144  }
   145  
   146  // GetOriginalError returns the original error
   147  func GetOriginalError(err error) error {
   148  	if blendedErr, ok := err.(blendedError); ok {
   149  		return blendedErr.originalError
   150  	}
   151  
   152  	return nil
   153  }