mirror of
https://github.com/MontFerret/ferret.git
synced 2025-12-01 22:19:32 +02:00
* Added new member path resolution logic * Updated Getter and Setter interfaces * Added ssupport of pre-compiled static member path * Improved error handling
144 lines
3.5 KiB
Go
144 lines
3.5 KiB
Go
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type (
|
|
SourceErrorDetail struct {
|
|
error
|
|
BaseError error
|
|
ComputeError error
|
|
}
|
|
|
|
// PathError represents an interface of
|
|
// error type which returned when an error occurs during an execution of Getter.GetIn or Setter.SetIn functions
|
|
// and contains segment of a given path that caused the error.
|
|
PathError interface {
|
|
error
|
|
Cause() error
|
|
Segment() int
|
|
Format(path []Value) string
|
|
}
|
|
|
|
// NativePathError represents a default implementation of GetterError interface.
|
|
NativePathError struct {
|
|
cause error
|
|
segment int
|
|
}
|
|
)
|
|
|
|
// NewPathError is a constructor function of NativePathError struct.
|
|
func NewPathError(err error, segment int) PathError {
|
|
return &NativePathError{
|
|
cause: err,
|
|
segment: segment,
|
|
}
|
|
}
|
|
|
|
// NewPathErrorFrom is a constructor function of NativePathError struct
|
|
// that accepts nested PathError and original segment index.
|
|
// It sums indexes to get the correct one that points to original path.
|
|
func NewPathErrorFrom(err PathError, segment int) PathError {
|
|
return NewPathError(err.Cause(), err.Segment()+segment)
|
|
}
|
|
|
|
func (e *NativePathError) Cause() error {
|
|
return e.cause
|
|
}
|
|
|
|
func (e *NativePathError) Error() string {
|
|
return e.cause.Error()
|
|
}
|
|
|
|
func (e *NativePathError) Segment() int {
|
|
return e.segment
|
|
}
|
|
|
|
func (e *NativePathError) Format(path []Value) string {
|
|
err := e.cause
|
|
|
|
if err == ErrInvalidPath && len(path) > e.segment {
|
|
return err.Error() + " '" + path[e.segment].String() + "'"
|
|
}
|
|
|
|
return err.Error()
|
|
}
|
|
|
|
func (e *SourceErrorDetail) Error() string {
|
|
return e.ComputeError.Error()
|
|
}
|
|
|
|
var (
|
|
ErrMissedArgument = errors.New("missed argument")
|
|
ErrInvalidArgument = errors.New("invalid argument")
|
|
ErrInvalidArgumentNumber = errors.New("invalid argument number")
|
|
ErrInvalidType = errors.New("invalid type")
|
|
ErrInvalidOperation = errors.New("invalid operation")
|
|
ErrNotFound = errors.New("not found")
|
|
ErrNotUnique = errors.New("not unique")
|
|
ErrTerminated = errors.New("operation is terminated")
|
|
ErrUnexpected = errors.New("unexpected error")
|
|
ErrTimeout = errors.New("operation timed out")
|
|
ErrNotImplemented = errors.New("not implemented")
|
|
ErrNotSupported = errors.New("not supported")
|
|
ErrNoMoreData = errors.New("no more data")
|
|
ErrInvalidPath = errors.New("cannot read property")
|
|
)
|
|
|
|
const typeErrorTemplate = "expected %s, but got %s"
|
|
|
|
func SourceError(src SourceMap, err error) error {
|
|
return &SourceErrorDetail{
|
|
BaseError: err,
|
|
ComputeError: errors.Errorf("%s: %s", err.Error(), src.String()),
|
|
}
|
|
}
|
|
|
|
func TypeError(actual Type, expected ...Type) error {
|
|
if len(expected) == 0 {
|
|
return Error(ErrInvalidType, actual.String())
|
|
}
|
|
|
|
if len(expected) == 1 {
|
|
return Error(ErrInvalidType, fmt.Sprintf(typeErrorTemplate, expected, actual))
|
|
}
|
|
|
|
strs := make([]string, len(expected))
|
|
|
|
for idx, t := range expected {
|
|
strs[idx] = t.String()
|
|
}
|
|
|
|
expectedStr := strings.Join(strs, " or ")
|
|
|
|
return Error(ErrInvalidType, fmt.Sprintf(typeErrorTemplate, expectedStr, actual))
|
|
}
|
|
|
|
func Error(err error, msg string) error {
|
|
return errors.Errorf("%s: %s", err.Error(), msg)
|
|
}
|
|
|
|
func Errorf(err error, format string, args ...interface{}) error {
|
|
return errors.Errorf("%s: %s", err.Error(), fmt.Sprintf(format, args...))
|
|
}
|
|
|
|
func Errors(err ...error) error {
|
|
message := ""
|
|
|
|
for _, e := range err {
|
|
if e != nil {
|
|
message += ": " + e.Error()
|
|
}
|
|
}
|
|
|
|
return errors.New(message)
|
|
}
|
|
|
|
func IsNoMoreData(err error) bool {
|
|
return err == ErrNoMoreData
|
|
}
|