From e62a766058516974f41f003eae9655e873506d43 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 7 Jul 2021 00:38:19 +0300 Subject: [PATCH] state: move nil check down to stackitem JSON processing We want to return real errors, not some generic thing for any kind of thing happening. --- pkg/core/state/notification_event.go | 4 ---- pkg/core/state/notification_event_test.go | 8 +++++++- pkg/vm/stackitem/json.go | 9 +++++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pkg/core/state/notification_event.go b/pkg/core/state/notification_event.go index 193fc8667..06e77184a 100644 --- a/pkg/core/state/notification_event.go +++ b/pkg/core/state/notification_event.go @@ -194,10 +194,6 @@ func (e Execution) MarshalJSON() ([]byte, error) { var errRecursive = []byte(`"error: recursive reference"`) arr := make([]json.RawMessage, len(e.Stack)) for i := range arr { - if e.Stack[i] == nil { - arr[i] = errRecursive - continue - } data, err := stackitem.ToJSONWithTypes(e.Stack[i]) if err != nil { data = errRecursive diff --git a/pkg/core/state/notification_event_test.go b/pkg/core/state/notification_event_test.go index 55e36f3aa..2f6667f61 100644 --- a/pkg/core/state/notification_event_test.go +++ b/pkg/core/state/notification_event_test.go @@ -184,7 +184,13 @@ func TestMarshalUnmarshalJSONAppExecResult(t *testing.T) { bs1, err := json.Marshal(actual) require.NoError(t, err) - require.Equal(t, bs, bs1) + require.NotEqual(t, bs, bs1) // recursive ref error vs. unserializable nil + + actual2 := new(AppExecResult) + require.NoError(t, json.Unmarshal(bs, actual2)) + bs2, err := json.Marshal(actual2) + require.NoError(t, err) + require.Equal(t, bs1, bs2) // unserializable nil in both cases }) t.Run("UnmarshalJSON error", func(t *testing.T) { diff --git a/pkg/vm/stackitem/json.go b/pkg/vm/stackitem/json.go index a431d73b9..b930344ba 100644 --- a/pkg/vm/stackitem/json.go +++ b/pkg/vm/stackitem/json.go @@ -232,10 +232,6 @@ func toJSONWithTypes(item Item, seen map[Item]bool) (interface{}, error) { if len(seen) > MaxJSONDepth { return "", ErrTooDeep } - typ := item.Type() - result := map[string]interface{}{ - "type": typ.String(), - } var value interface{} switch it := item.(type) { case *Array, *Struct: @@ -281,6 +277,11 @@ func toJSONWithTypes(item Item, seen map[Item]bool) (interface{}, error) { delete(seen, item) case *Pointer: value = it.pos + case nil: + return "", fmt.Errorf("%w: nil", ErrUnserializable) + } + result := map[string]interface{}{ + "type": item.Type().String(), } if value != nil { result["value"] = value