github.com/MontFerret/ferret@v0.18.0/pkg/runtime/core/errors.go (about)

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  type (
    11  	SourceErrorDetail struct {
    12  		error
    13  		BaseError    error
    14  		ComputeError error
    15  	}
    16  
    17  	// PathError represents an interface of
    18  	// error type which returned when an error occurs during an execution of Getter.GetIn or Setter.SetIn functions
    19  	// and contains segment of a given path that caused the error.
    20  	PathError interface {
    21  		error
    22  		Cause() error
    23  		Segment() int
    24  		Format(path []Value) string
    25  	}
    26  
    27  	// NativePathError represents a default implementation of GetterError interface.
    28  	NativePathError struct {
    29  		cause   error
    30  		segment int
    31  	}
    32  )
    33  
    34  // NewPathError is a constructor function of NativePathError struct.
    35  func NewPathError(err error, segment int) PathError {
    36  	return &NativePathError{
    37  		cause:   err,
    38  		segment: segment,
    39  	}
    40  }
    41  
    42  // NewPathErrorFrom is a constructor function of NativePathError struct
    43  // that accepts nested PathError and original segment index.
    44  // It sums indexes to get the correct one that points to original path.
    45  func NewPathErrorFrom(err PathError, segment int) PathError {
    46  	return NewPathError(err.Cause(), err.Segment()+segment)
    47  }
    48  
    49  func (e *NativePathError) Cause() error {
    50  	return e.cause
    51  }
    52  
    53  func (e *NativePathError) Error() string {
    54  	return e.cause.Error()
    55  }
    56  
    57  func (e *NativePathError) Segment() int {
    58  	return e.segment
    59  }
    60  
    61  func (e *NativePathError) Format(path []Value) string {
    62  	err := e.cause
    63  
    64  	if err == ErrInvalidPath && len(path) > e.segment {
    65  		return err.Error() + " '" + path[e.segment].String() + "'"
    66  	}
    67  
    68  	return err.Error()
    69  }
    70  
    71  func (e *SourceErrorDetail) Error() string {
    72  	return e.ComputeError.Error()
    73  }
    74  
    75  var (
    76  	ErrMissedArgument        = errors.New("missed argument")
    77  	ErrInvalidArgument       = errors.New("invalid argument")
    78  	ErrInvalidArgumentNumber = errors.New("invalid argument number")
    79  	ErrInvalidType           = errors.New("invalid type")
    80  	ErrInvalidOperation      = errors.New("invalid operation")
    81  	ErrNotFound              = errors.New("not found")
    82  	ErrNotUnique             = errors.New("not unique")
    83  	ErrTerminated            = errors.New("operation is terminated")
    84  	ErrUnexpected            = errors.New("unexpected error")
    85  	ErrTimeout               = errors.New("operation timed out")
    86  	ErrNotImplemented        = errors.New("not implemented")
    87  	ErrNotSupported          = errors.New("not supported")
    88  	ErrNoMoreData            = errors.New("no more data")
    89  	ErrInvalidPath           = errors.New("cannot read property")
    90  	ErrDone                  = errors.New("operation done")
    91  )
    92  
    93  const typeErrorTemplate = "expected %s, but got %s"
    94  
    95  func SourceError(src SourceMap, err error) error {
    96  	return &SourceErrorDetail{
    97  		BaseError:    err,
    98  		ComputeError: errors.Errorf("%s: %s", err.Error(), src.String()),
    99  	}
   100  }
   101  
   102  func TypeError(actual Type, expected ...Type) error {
   103  	if len(expected) == 0 {
   104  		return Error(ErrInvalidType, actual.String())
   105  	}
   106  
   107  	if len(expected) == 1 {
   108  		return Error(ErrInvalidType, fmt.Sprintf(typeErrorTemplate, expected, actual))
   109  	}
   110  
   111  	strs := make([]string, len(expected))
   112  
   113  	for idx, t := range expected {
   114  		strs[idx] = t.String()
   115  	}
   116  
   117  	expectedStr := strings.Join(strs, " or ")
   118  
   119  	return Error(ErrInvalidType, fmt.Sprintf(typeErrorTemplate, expectedStr, actual))
   120  }
   121  
   122  func Error(err error, msg string) error {
   123  	return errors.Errorf("%s: %s", err.Error(), msg)
   124  }
   125  
   126  func Errorf(err error, format string, args ...interface{}) error {
   127  	return errors.Errorf("%s: %s", err.Error(), fmt.Sprintf(format, args...))
   128  }
   129  
   130  func Errors(err ...error) error {
   131  	message := ""
   132  
   133  	for _, e := range err {
   134  		if e != nil {
   135  			message += ": " + e.Error()
   136  		}
   137  	}
   138  
   139  	return errors.New(message)
   140  }
   141  
   142  func IsNoMoreData(err error) bool {
   143  	return err == ErrNoMoreData
   144  }
   145  
   146  func IsDone(err error) bool {
   147  	return err == ErrDone
   148  }