Skip to content

Commit

Permalink
Include field name in decoding errors (#3866) (#3872)
Browse files Browse the repository at this point in the history
  • Loading branch information
jalvz authored Jun 11, 2020
1 parent e17593a commit 4613015
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 48 deletions.
2 changes: 1 addition & 1 deletion model/modeldecoder/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestDecodeContext(t *testing.T) {
input: map[string]interface{}{
"request": map[string]interface{}{
"url": map[string]interface{}{"raw": "127.0.0.1"}}},
errOut: utility.ErrFetch.Error(),
errOut: utility.ErrFetch("method", nil).Error(),
},
"no_url_protocol": {
input: map[string]interface{}{
Expand Down
18 changes: 6 additions & 12 deletions model/modeldecoder/metricset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ import (
"testing"
"time"

"github.com/stretchr/testify/assert"

"github.com/elastic/beats/v7/libbeat/common"

"github.com/stretchr/testify/assert"

"github.com/elastic/apm-server/model"
"github.com/elastic/apm-server/utility"
)

// assertMetricsMatch is an equality test for a metricset as sample order is not important
Expand All @@ -55,22 +54,19 @@ func TestDecode(t *testing.T) {

for _, test := range []struct {
input map[string]interface{}
err error
err bool
metricset *model.Metricset
}{
{input: nil, err: nil, metricset: nil},
{input: nil, metricset: nil},
{
input: map[string]interface{}{},
err: nil,
metricset: nil,
},
{
input: map[string]interface{}{
"timestamp": tsFormat(timestampParsed),
"samples": map[string]interface{}{},
},

err: nil,
metricset: &model.Metricset{
Metadata: metadata,
Timestamp: timestampParsed,
Expand All @@ -85,7 +81,7 @@ func TestDecode(t *testing.T) {
},
},
},
err: utility.ErrFetch,
err: true,
},
{
input: map[string]interface{}{
Expand All @@ -111,7 +107,6 @@ func TestDecode(t *testing.T) {
},
},
},
err: nil,
metricset: &model.Metricset{
Metadata: metadata,
Samples: []model.Sample{
Expand Down Expand Up @@ -150,7 +145,6 @@ func TestDecode(t *testing.T) {
"name": trName,
},
},
err: nil,
metricset: &model.Metricset{
Metadata: metadata,
Samples: []model.Sample{
Expand All @@ -174,7 +168,7 @@ func TestDecode(t *testing.T) {
RequestTime: requestTime,
Metadata: metadata,
}, batch)
if test.err != nil {
if test.err == true {
assert.Error(t, err)
}
if test.metricset != nil {
Expand Down
39 changes: 21 additions & 18 deletions utility/data_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ type ManualDecoder struct {
Err error
}

var (
ErrFetch = errors.New("error fetching field")
)
func ErrFetch(field string, path []string) error {
if path != nil {
field = strings.Join(path, ".") + "." + field
}
return errors.New("error fetching field " + field)
}

func (d *ManualDecoder) Float64(base map[string]interface{}, key string, keys ...string) float64 {
val := getDeep(base, keys...)[key]
Expand All @@ -49,7 +52,7 @@ func (d *ManualDecoder) Float64(base map[string]interface{}, key string, keys ..
}
}

d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return 0.0
}

Expand All @@ -67,7 +70,7 @@ func (d *ManualDecoder) Float64Ptr(base map[string]interface{}, key string, keys
}
}

d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

Expand All @@ -93,7 +96,7 @@ func (d *ManualDecoder) IntPtr(base map[string]interface{}, key string, keys ...
return &valInt
}
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

Expand All @@ -114,15 +117,15 @@ func (d *ManualDecoder) Int64Ptr(base map[string]interface{}, key string, keys .
return &valInt
}
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

func (d *ManualDecoder) Int(base map[string]interface{}, key string, keys ...string) int {
if val := d.IntPtr(base, key, keys...); val != nil {
return *val
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return 0
}

Expand All @@ -134,15 +137,15 @@ func (d *ManualDecoder) StringPtr(base map[string]interface{}, key string, keys
if valStr, ok := val.(string); ok {
return &valStr
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

func (d *ManualDecoder) String(base map[string]interface{}, key string, keys ...string) string {
if val := d.StringPtr(base, key, keys...); val != nil {
return *val
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return ""
}

Expand All @@ -156,7 +159,7 @@ func (d *ManualDecoder) NetIP(base map[string]interface{}, key string, keys ...s
if valStr, ok := val.(string); ok {
return ParseIP(valStr)
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

Expand All @@ -172,7 +175,7 @@ func (d *ManualDecoder) StringArr(base map[string]interface{}, key string, keys
if valStr, ok := v.(string); ok {
strArr[idx] = valStr
} else {
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}
}
Expand All @@ -181,7 +184,7 @@ func (d *ManualDecoder) StringArr(base map[string]interface{}, key string, keys
if strArr, ok := arr.([]string); ok {
return strArr
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

Expand All @@ -196,7 +199,7 @@ func (d *ManualDecoder) InterfaceArr(base map[string]interface{}, key string, ke
} else if valArr, ok := val.([]interface{}); ok {
return valArr
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

Expand All @@ -207,7 +210,7 @@ func (d *ManualDecoder) BoolPtr(base map[string]interface{}, key string, keys ..
} else if valBool, ok := val.(bool); ok {
return &valBool
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

Expand All @@ -218,7 +221,7 @@ func (d *ManualDecoder) MapStr(base map[string]interface{}, key string, keys ...
} else if valMapStr, ok := val.(map[string]interface{}); ok {
return valMapStr
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return nil
}

Expand All @@ -232,7 +235,7 @@ func (d *ManualDecoder) TimeRFC3339(base map[string]interface{}, key string, key
return valTime
}
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return time.Time{}
}

Expand All @@ -249,7 +252,7 @@ func (d *ManualDecoder) TimeEpochMicro(base map[string]interface{}, key string,
return time.Unix(sec, microsec*1000).UTC()
}
}
d.Err = ErrFetch
d.Err = ErrFetch(key, keys)
return time.Time{}
}

Expand Down
34 changes: 17 additions & 17 deletions utility/data_fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ func TestFloat64(t *testing.T) {
for _, test := range []testStr{
{key: "fl64", keys: []string{"a", "b"}, out: fl64Also, err: nil},
{key: "fl64", keys: []string{}, out: fl64, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: 0.0, err: ErrFetch},
{key: "str", keys: []string{"a", "b"}, out: 0.0, err: ErrFetch},
{key: "missing", keys: []string{"a", "b"}, out: 0.0, err: ErrFetch("missing", []string{"a", "b"})},
{key: "str", keys: []string{"a", "b"}, out: 0.0, err: ErrFetch("str", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.Float64(decoderBase, test.key, test.keys...)
Expand All @@ -81,7 +81,7 @@ func TestFloat64Ptr(t *testing.T) {
{key: "fl64", keys: []string{"a", "b"}, out: &fl64Also, err: nil},
{key: "fl64", keys: []string{}, out: &fl64, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outnil, err: nil},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("str", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.Float64Ptr(decoderBase, test.key, test.keys...)
Expand All @@ -96,7 +96,7 @@ func TestIntPtr(t *testing.T) {
{key: "intfl32", keys: []string{}, out: &intFl32, err: nil},
{key: "intfl64", keys: []string{}, out: &intFl64, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outnil, err: nil},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("str", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.IntPtr(decoderBase, test.key, test.keys...)
Expand All @@ -111,7 +111,7 @@ func TestInt64Ptr(t *testing.T) {
for _, test := range []testStr{
{key: "intfl64", keys: []string{}, out: &int64Fl64, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outnil, err: nil},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("str", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.Int64Ptr(decoderBase, test.key, test.keys...)
Expand All @@ -124,8 +124,8 @@ func TestInt(t *testing.T) {
for _, test := range []testStr{
{key: "intfl32", keys: []string{}, out: intFl32, err: nil},
{key: "intfl64", keys: []string{}, out: intFl64, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: 0, err: ErrFetch},
{key: "str", keys: []string{"a", "b"}, out: 0, err: ErrFetch},
{key: "missing", keys: []string{"a", "b"}, out: 0, err: ErrFetch("missing", []string{"a", "b"})},
{key: "str", keys: []string{"a", "b"}, out: 0, err: ErrFetch("str", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.Int(decoderBase, test.key, test.keys...)
Expand All @@ -140,7 +140,7 @@ func TestStrPtr(t *testing.T) {
{key: "str", keys: []string{}, out: &str, err: nil},
{key: "str", keys: []string{"a", "b"}, out: &str2, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outnil, err: nil},
{key: "int", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "int", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("int", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.StringPtr(decoderBase, test.key, test.keys...)
Expand All @@ -153,8 +153,8 @@ func TestStr(t *testing.T) {
for _, test := range []testStr{
{key: "str", keys: []string{}, out: str, err: nil},
{key: "str", keys: []string{"a", "b"}, out: str2, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: "", err: ErrFetch},
{key: "int", keys: []string{"a", "b"}, out: "", err: ErrFetch},
{key: "missing", keys: []string{"a", "b"}, out: "", err: ErrFetch("missing", []string{"a", "b"})},
{key: "int", keys: []string{"a", "b"}, out: "", err: ErrFetch("int", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.String(decoderBase, test.key, test.keys...)
Expand All @@ -169,8 +169,8 @@ func TestStrArray(t *testing.T) {
{key: "strArr", keys: []string{}, out: []string{"c", "d"}, err: nil},
{key: "strArr", keys: []string{"a", "b"}, out: []string{"k", "d"}, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outnil, err: nil},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "intArr", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("str", []string{"a", "b"})},
{key: "intArr", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("intArr", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.StringArr(decoderBase, test.key, test.keys...)
Expand Down Expand Up @@ -201,7 +201,7 @@ func TestInterfaceArray(t *testing.T) {
for _, test := range []testStr{
{key: "strArr", keys: []string{"a", "b"}, out: []interface{}{"k", "d"}, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outnil, err: nil},
{key: "int", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "int", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("int", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.InterfaceArr(decoderBase, test.key, test.keys...)
Expand All @@ -215,7 +215,7 @@ func TestBoolPtr(t *testing.T) {
{key: "true", keys: []string{}, out: &boolTrue, err: nil},
{key: "false", keys: []string{"a", "b"}, out: &boolFalse, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outnil, err: nil},
{key: "int", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "int", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("int", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.BoolPtr(decoderBase, test.key, test.keys...)
Expand All @@ -229,7 +229,7 @@ func TestMapStr(t *testing.T) {
{key: "a", keys: []string{}, out: decoderBase["a"], err: nil},
{key: "b", keys: []string{"a"}, out: decoderBase["a"].(map[string]interface{})["b"], err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outnil, err: nil},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch},
{key: "str", keys: []string{"a", "b"}, out: outnil, err: ErrFetch("str", []string{"a", "b"})},
} {
decoder := ManualDecoder{}
out := decoder.MapStr(decoderBase, test.key, test.keys...)
Expand All @@ -244,8 +244,8 @@ func TestTimeRFC3339(t *testing.T) {
for _, test := range []testStr{
{key: "time", keys: []string{}, out: tp, err: nil},
{key: "missing", keys: []string{"a", "b"}, out: outZero, err: nil},
{key: "str", keys: []string{"a", "b"}, out: outZero, err: ErrFetch},
{key: "b", keys: []string{"a"}, out: outZero, err: ErrFetch},
{key: "str", keys: []string{"a", "b"}, out: outZero, err: ErrFetch("str", []string{"a", "b"})},
{key: "b", keys: []string{"a"}, out: outZero, err: ErrFetch("b", []string{"a"})},
} {
decoder := ManualDecoder{}
out := decoder.TimeRFC3339(decoderBase, test.key, test.keys...)
Expand Down

0 comments on commit 4613015

Please sign in to comment.