diff --git a/jsonapi/errors.go b/jsonapi/errors.go new file mode 100644 index 0000000..d24df0f --- /dev/null +++ b/jsonapi/errors.go @@ -0,0 +1,44 @@ +package jsonapi + +import "errors" + +//Error for all errors within this package +type Error interface { + error +} + +//MarshalError interface +type MarshalError interface { + Error +} + +//UnmarshalError interface +type UnmarshalError interface { + Error +} + +// Marshal errors +var ( + // ErrInvalidMarshalType is returned if marshal is called with an invalid type + ErrInvalidMarshalType MarshalError = errors.New("Marshal only accepts slice, struct or ptr types") + // ErrNonHomogenousSlice if any element within a slice does not implement marshal identifier + ErrNonHomogenousSlice MarshalError = errors.New("all elements within the slice must implement api2go.MarshalIdentifier") + //ErrNonNilElement marshaling a nil type is not possible + ErrNonNilElement MarshalError = errors.New("MarshalIdentifier must not be nil") +) + +// Unmarshal errors +var ( + // ErrNilTarget if element will be unmarshalled into a nil element + ErrNilTarget UnmarshalError = errors.New("target must not be nil") + // ErrNonPointerTarget + ErrNonPointerTarget UnmarshalError = errors.New("target must be a ptr") +) + +// Semantic errors +var ( + ErrInvalidUnmarshalType UnmarshalError = errors.New("target must implement UnmarshalIdentifier interface") + ErrEmptySource UnmarshalError = errors.New(`Source JSON is empty and has no "attributes" payload object`) + ErrMissingType UnmarshalError = errors.New("invalid record, no type was specified") + ErrInvalidStruct UnmarshalError = errors.New("existing structs must implement interface MarshalIdentifier") +) diff --git a/jsonapi/marshal.go b/jsonapi/marshal.go index 891b5f9..bb19864 100644 --- a/jsonapi/marshal.go +++ b/jsonapi/marshal.go @@ -2,7 +2,6 @@ package jsonapi import ( "encoding/json" - "errors" "fmt" "reflect" "strings" @@ -132,7 +131,7 @@ func MarshalToStruct(data interface{}, information ServerInformation) (*Document case reflect.Struct, reflect.Ptr: return marshalStruct(data.(MarshalIdentifier), information) default: - return nil, errors.New("Marshal only accepts slice, struct or ptr types") + return nil, ErrInvalidMarshalType } } @@ -168,7 +167,7 @@ func marshalSlice(data interface{}, information ServerInformation) (*Document, e k := val.Index(i).Interface() element, ok := k.(MarshalIdentifier) if !ok { - return nil, errors.New("all elements within the slice must implement api2go.MarshalIdentifier") + return nil, ErrNonHomogenousSlice } err := marshalData(element, &dataElements[i], information) @@ -228,7 +227,7 @@ func filterDuplicates(input []MarshalIdentifier, information ServerInformation) func marshalData(element MarshalIdentifier, data *Data, information ServerInformation) error { refValue := reflect.ValueOf(element) if refValue.Kind() == reflect.Ptr && refValue.IsNil() { - return errors.New("MarshalIdentifier must not be nil") + return ErrNonNilElement } attributes, err := json.Marshal(element) diff --git a/jsonapi/unmarshal.go b/jsonapi/unmarshal.go index 9710ee5..fac8936 100644 --- a/jsonapi/unmarshal.go +++ b/jsonapi/unmarshal.go @@ -2,7 +2,6 @@ package jsonapi import ( "encoding/json" - "errors" "fmt" "reflect" ) @@ -80,11 +79,11 @@ type EditToManyRelations interface { // must implement the `UnmarshalIdentifier` interface. func Unmarshal(data []byte, target interface{}) error { if target == nil { - return errors.New("target must not be nil") + return ErrNilTarget } if reflect.TypeOf(target).Kind() != reflect.Ptr { - return errors.New("target must be a ptr") + return ErrNonPointerTarget } ctx := &Document{} @@ -95,7 +94,7 @@ func Unmarshal(data []byte, target interface{}) error { } if ctx.Data == nil { - return errors.New(`Source JSON is empty and has no "attributes" payload object`) + return ErrEmptySource } if ctx.Data.DataObject != nil { @@ -118,8 +117,9 @@ func Unmarshal(data []byte, target interface{}) error { for i := 0; i < targetValue.Len(); i++ { marshalCasted, ok := targetValue.Index(i).Interface().(MarshalIdentifier) if !ok { - return errors.New("existing structs must implement interface MarshalIdentifier") + return ErrInvalidStruct } + if record.ID == marshalCasted.GetID() { targetRecord = targetValue.Index(i).Addr() break @@ -150,11 +150,11 @@ func Unmarshal(data []byte, target interface{}) error { func setDataIntoTarget(data *Data, target interface{}) error { castedTarget, ok := target.(UnmarshalIdentifier) if !ok { - return errors.New("target must implement UnmarshalIdentifier interface") + return ErrInvalidUnmarshalType } if data.Type == "" { - return errors.New("invalid record, no type was specified") + return ErrMissingType } err := checkType(data.Type, castedTarget)