Skip to content

Commit

Permalink
improved unmarshal error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
adranwit committed Sep 6, 2024
1 parent 46211f2 commit bd065ff
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 3 deletions.
28 changes: 28 additions & 0 deletions gateway/router/marshal/json/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package json

import (
"fmt"
"strings"
)

// Error represents a json unmarshal error
type Error struct {
Path string
Err error
}

func (e *Error) Error() string {
return fmt.Sprintf("failed to unmarshal %s, %v", e.Path, e.Err)
}

func NewError(path string, err error) *Error {
if jErr, ok := err.(*Error); ok {
if strings.HasPrefix(jErr.Path, "[") {
path = path + jErr.Path
} else {
path = path + "." + jErr.Path
}
err = jErr.Err
}
return &Error{Path: path, Err: err}
}
12 changes: 12 additions & 0 deletions gateway/router/marshal/json/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var unmarshallerIntoType = reflect.TypeOf((*UnmarshalerInto)(nil)).Elem()
var mapStringIfaceType = reflect.TypeOf(map[string]interface{}{})
var decData *xunsafe.Field
var decCur *xunsafe.Field
var decErr *xunsafe.Field

func init() {
ResetCache()
Expand All @@ -25,6 +26,17 @@ func init() {
if decCurField, ok := reflect.TypeOf(gojay.Decoder{}).FieldByName("cursor"); ok {
decCur = xunsafe.NewField(decCurField)
}
if decCurField, ok := reflect.TypeOf(gojay.Decoder{}).FieldByName("err"); ok {
decErr = xunsafe.NewField(decCurField)
}
}

func decoderError(decoder *gojay.Decoder) error {
if decErr == nil {
return nil
}
decPtr := unsafe.Pointer(decoder)
return decErr.Error(decPtr)
}

func ResetCache() {
Expand Down
8 changes: 7 additions & 1 deletion gateway/router/marshal/json/marshaller_slice.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package json

import (
"fmt"
"github.com/francoispqt/gojay"
"github.com/viant/datly/gateway/router/marshal/config"
"github.com/viant/tagly/format"
Expand Down Expand Up @@ -111,7 +112,12 @@ func newSliceDecoder(rType reflect.Type, ptr unsafe.Pointer, xslice *xunsafe.Sli

func (s *sliceDecoder) UnmarshalJSONArray(d *gojay.Decoder) error {
add := s.appender.Add()
return s.unmarshaller.UnmarshallObject(xunsafe.AsPointer(add), d, nil, s.session)
err := s.unmarshaller.UnmarshallObject(xunsafe.AsPointer(add), d, nil, s.session)
if err != nil {
l := s.appender.Len()
return NewError(fmt.Sprintf("[%d]", l-1), err)
}
return nil
}

func newSliceInterfaceMarshaller(config *config.IOConfig, path string, outputPath string, tag *format.Tag, cache *marshallersCache) marshaler {
Expand Down
18 changes: 17 additions & 1 deletion gateway/router/marshal/json/marshaller_struct.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package json

import (
"fmt"
"github.com/francoispqt/gojay"
"github.com/viant/datly/gateway/router/marshal/config"
structology "github.com/viant/structology"
Expand Down Expand Up @@ -436,6 +437,18 @@ func groupFields(elemType reflect.Type) *groupedFields {
}

func (d *structDecoder) UnmarshalJSONObject(decoder *gojay.Decoder, fieldName string) error {
fmt.Println("UnmarshalJSONObject", fieldName)
err := d.unmarshalJson(decoder, fieldName)
if err == nil {
err = decoderError(decoder)
}
if err != nil {
return NewError(fieldName, err)
}
return err
}

func (d *structDecoder) unmarshalJson(decoder *gojay.Decoder, fieldName string) error {
marshaller, ok := d.marshaller.marshallerByName(fieldName)
if !ok {
return nil
Expand All @@ -444,7 +457,10 @@ func (d *structDecoder) UnmarshalJSONObject(decoder *gojay.Decoder, fieldName st
if len(d.session.PathMarshaller) > 0 {
interceptor, ok := d.session.PathMarshaller[marshaller.path]
if ok {
return interceptor(marshaller.xField.Addr(d.ptr), decoder, d.session.Options...)
if err := interceptor(marshaller.xField.Addr(d.ptr), decoder, d.session.Options...); err != nil {
return err
}
return nil
}
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ require (
github.com/viant/toolbox v0.36.0
github.com/viant/velty v0.2.1-0.20230927172116-ba56497b5c85
github.com/viant/xreflect v0.6.2
github.com/viant/xunsafe v0.9.3
github.com/viant/xunsafe v0.9.4
golang.org/x/mod v0.16.0
golang.org/x/oauth2 v0.19.0 // indirect
google.golang.org/api v0.174.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,8 @@ github.com/viant/xreflect v0.6.2 h1:PzpiTHHMwqMV2ScDJph+pMkk+JvuXFZFj6xwnM/E6sc=
github.com/viant/xreflect v0.6.2/go.mod h1:BwI+lqFjhKv2Vn4E0Jt6nvbwcFOWrM6H+sOMOX3JiU4=
github.com/viant/xunsafe v0.9.3 h1:XvV6c0AWpyq2cdJmBDJn73tcJ4FE3w3LRJWdiRR+wNk=
github.com/viant/xunsafe v0.9.3/go.mod h1:V3RCwtqpbNPznhmHysyAOpsyuSVkIYWo1Ewip7qb9/s=
github.com/viant/xunsafe v0.9.4 h1:FcebICUWn1ZLJNdp7pGCpJGpjh2cT5YKFoWE79h9jkw=
github.com/viant/xunsafe v0.9.4/go.mod h1:V3RCwtqpbNPznhmHysyAOpsyuSVkIYWo1Ewip7qb9/s=
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca h1:uvPMDVyP7PXMMioYdyPH+0O+Ta/UO1WFfNYMO3Wz0eg=
github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
Expand Down

0 comments on commit bd065ff

Please sign in to comment.