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 }